Guest User

Untitled

a guest
May 1st, 2016
44
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.79 KB | None | 0 0
  1. #include <opencv2/opencv.hpp>
  2.  
  3. #include <iostream>
  4. #include <vector>
  5. #include <cmath>
  6. #include <assert.h>
  7.  
  8. using namespace std;
  9. using namespace cv;
  10.  
  11. #define MASK_BACKGROUND (1<<7)
  12. #define MAX_ITERATION 300
  13.  
  14. inline uchar clampValue (float val) {
  15. if (val > 255) return 255;
  16. else if (val < 0) return 0;
  17. else return (uchar)val;
  18. }
  19.  
  20. void montage (IplImage* srcImage, IplImage* destImage, IplImage* maskImage) {
  21. if (!srcImage || !destImage || !maskImage) {
  22. cerr << "cannot find image file" << endl;
  23. exit(-1);
  24. }
  25.  
  26. int w = srcImage->width;
  27. int h = srcImage->height;
  28.  
  29. if (w != maskImage->width || h != maskImage->height) {
  30. cerr << "mask size doesn't match src size" << endl;
  31. exit(-1);
  32. }
  33.  
  34. vector<int> destPoints;
  35. vector<int> constants;
  36.  
  37. int size=0;
  38. for (int y=0; y<h; y++) {
  39. for (int x=0; x<w; x++) {
  40. int maskIndex = maskImage->widthStep * y + x;
  41. uchar c = maskImage->imageData[maskIndex];
  42. //printf("%d\n", (int)c);
  43. //if (!(c & MASK_BACKGROUND)) {
  44. if (c & MASK_BACKGROUND) {
  45. //printf("input (%d,%d)\n", x, y);
  46. int destIndex = destImage->widthStep * y + (x * 3);
  47. destPoints.push_back(destIndex);
  48.  
  49. int srcIndex = srcImage->widthStep * y + (x * 3);
  50.  
  51. int constant[3] = {0};
  52. int sum1[3]={0};
  53. int sum2[3]={0};
  54. // right
  55. if (x < srcImage->width-1) {
  56. for (int i=0; i<3; i++) {
  57. int val1 = (uchar)(destImage->imageData[destIndex+3+i]) - (uchar)(destImage->imageData[destIndex+i]);
  58. int val2 = (uchar)(srcImage->imageData[srcIndex+3+i]) - (uchar)(srcImage->imageData[srcIndex+i]);
  59. //printf("%d,%d\n", val1, val2);
  60. //constant[i] += min(val1, val2);
  61. sum1[i]+=val1;
  62. sum2[i]+=val2;
  63. //constant[i] += val2;
  64. }
  65. }
  66. // left
  67. if (x > 0) {
  68. for (int i=0; i<3; i++) {
  69. int val1 = (uchar)(destImage->imageData[destIndex-3+i]) - (uchar)(destImage->imageData[destIndex+i]);
  70. int val2 = (uchar)(srcImage->imageData[srcIndex-3+i]) - (uchar)(srcImage->imageData[srcIndex+i]);
  71. //printf("%d,%d\n", val1, val2);
  72. //constant[i] += min(val1, val2);
  73. sum1[i]+=val1;
  74. sum2[i]+=val2;
  75. //constant[i] += val2;
  76. }
  77. }
  78. // top
  79. if (y > 0) {
  80. for (int i=0; i<3; i++) {
  81. int val1 = (uchar)(destImage->imageData[destImage->widthStep*(y-1)+(x*3)+i]) - (uchar)(destImage->imageData[destIndex+i]);
  82. int val2 = (uchar)(srcImage->imageData[srcImage->widthStep*(y-1)+(x*3)+i]) - (uchar)(srcImage->imageData[srcIndex+i]);
  83. //printf("%d,%d\n", val1, val2);
  84. //constant[i] += min(val1, val2);
  85. sum1[i]+=val1;
  86. sum2[i]+=val2;
  87. //constant[i] += val2;
  88. }
  89. }
  90. // bottom
  91. if (y < srcImage->height-1) {
  92. for (int i=0; i<3; i++) {
  93. int val1 = (uchar)(destImage->imageData[destImage->widthStep*(y+1)+(x*3)+i]) - (uchar)(destImage->imageData[destIndex+i]);
  94. int val2 = (uchar)(srcImage->imageData[srcImage->widthStep*(y+1)+(x*3)+i]) - (uchar)(srcImage->imageData[srcIndex+i]);
  95. //printf("%d,%d\n", val1, val2);
  96. //constant[i] += min(val1, val2);
  97. sum1[i]+=val1;
  98. sum2[i]+=val2;
  99. //constant[i] += val2;
  100. }
  101. }
  102. for (int i=0; i<3; i++) {
  103. //constants.push_back(constant[i]);
  104. //if (abs(sum1[i]) > abs(sum2[i])){
  105. // constants.push_back(sum1[i]);
  106. //} else {
  107. constants.push_back(sum2[i]);
  108. //}
  109. }
  110. }
  111. // int offset = srcImage->widthStep * y + (x * 3);
  112. size++;
  113. }
  114. }
  115.  
  116. printf("destPoints size=%d\n", (int)destPoints.size());
  117. printf("constants size=%d\n", (int)constants.size());
  118. uchar* destImageData = (uchar*)destImage->imageData;
  119. cv::Mat final(3*destImage->width, destImage->height, DataType<float>::type);
  120. for (int x=0; x<destImage->width; x++) for (int y=0; y<destImage->height; y++)
  121. for (int i=0; i<3; i++)
  122. final.at<float>(x*3+i, y) = ((uchar)destImage->imageData[destImage->widthStep*y+3*x+i]);
  123.  
  124. //for (int x=0; x<destImage->width; x++) for (int y=0; y<destImage->height; y++)
  125. // printf("(%f,%f,%f)\n", final.at<float>(x*3+0, y), final.at<float>(x*3+1, y), final.at<float>(x*3+2, y));
  126.  
  127. // ヤコビ法で連立一次方程式を解く
  128. for (int loop=0; loop<MAX_ITERATION; loop++) {
  129. int n = destPoints.size();
  130. for (int p=0; p<n; p++) {
  131. int destIndex = destPoints[p];
  132. int y = destIndex / (destImage->widthStep);
  133. int x = (destIndex % (destImage->widthStep)) / 3;
  134. //printf("check (%d,%d)\n", x, y);
  135. float values[3] = {0};
  136. // right
  137. int count = 0;
  138. if (x < destImage->width-1) {
  139. count++;
  140. for (int i=0; i<3; i++) {
  141. //values[i] += (uchar)(destImageData[destIndex+3+i]);
  142. values[i] += final.at<float>((3*(x+1))+i, y);
  143. }
  144. }
  145. // left
  146. if (x > 0) {
  147. count++;
  148. for (int i=0; i<3; i++) {
  149. //values[i] += (uchar)(destImageData[destIndex-3+i]);
  150. values[i] += final.at<float>((3*(x-1))+i, y);
  151. }
  152. }
  153. // top
  154. if (y > 0) {
  155. count++;
  156. for (int i=0; i<3; i++) {
  157. //values[i] += (uchar)(destImageData[destImage->widthStep*(y-1)+(x*3)+i]);
  158. values[i] += final.at<float>((3*x)+i, y-1);
  159. }
  160. }
  161. // bottom
  162. if (y < destImage->height-1) {
  163. count++;
  164. for (int i=0; i<3; i++) {
  165. //values[i] += (uchar)(destImageData[destImage->widthStep*(y+1)+(x*3)+i]);
  166. values[i] += final.at<float>((3*x)+i, y+1);
  167. }
  168. }
  169. //for (int i=0; i<3; i++) {
  170. // values[i] -= count*((uchar)(destImageData[destIndex+i]));
  171. //}
  172. // 更新
  173. for (int j=0; j<3; j++) {
  174. float newval = (values[j] - constants[p*3+j]) / count;
  175. float oldval = final.at<float>((3*x)+j, y);
  176. //if (newval >= 256) newval = 255;
  177. //if (newval < 0) newval = 0;
  178. //destImageData[destIndex+j] = (uchar)newval;
  179. //printf("%f->%f\n", oldval, newval);
  180. final.at<float>((3*x)+j, y) = newval;
  181. }
  182. }
  183. }
  184.  
  185. {
  186. int n = destPoints.size();
  187. for (int p=0; p<n; p++) {
  188. int destIndex = destPoints[p];
  189. int y = destIndex / (destImage->widthStep);
  190. int x = (destIndex % (destImage->widthStep)) / 3;
  191. //printf("set (%d,%d)\n", x, y);
  192. for (int i=0; i<3; i++) {
  193. //printf(" %d->%d\n", x, y, (uchar)destImage->imageData[destIndex + i], clampValue(final.at<float>(x*3+i, y)));
  194. destImage->imageData[destIndex + i] = clampValue(final.at<float>(x*3+i, y));
  195. }
  196. }
  197. }
  198. return;
  199. }
  200.  
  201. int main(int argc, char** argv) {
  202. const char* srcFile = argc == 4 ? argv[1] : "black1.jpg";
  203. const char* destFile = argc == 4 ? argv[2] : "takahiro.jpg";
  204. //const char* filename2 = argc == 3 ? argv[2] : "photo2.jpg";
  205. const char* maskFile = argc == 4 ? argv[3] : "mask_black.jpg";
  206.  
  207. IplImage* srcImage = cvLoadImage(srcFile, CV_LOAD_IMAGE_ANYCOLOR|CV_LOAD_IMAGE_ANYDEPTH);
  208. IplImage* destImage = cvLoadImage(destFile, CV_LOAD_IMAGE_ANYCOLOR|CV_LOAD_IMAGE_ANYDEPTH);
  209. IplImage* maskImage = cvLoadImage(maskFile, CV_LOAD_IMAGE_GRAYSCALE);
  210.  
  211. if (!srcImage || !destImage) {
  212. cerr << "cannot find image file" << endl;
  213. exit(-1);
  214. }
  215.  
  216. int w = srcImage->width;
  217. int h = srcImage->height;
  218.  
  219. if (w != maskImage->width || h != maskImage->height) {
  220. cerr << "mask size doesn't match src size" << endl;
  221. exit(-1);
  222. }
  223.  
  224. montage(srcImage, destImage, maskImage);
  225.  
  226. cvShowImage("Poisson Image Editing", destImage);
  227. cvSaveImage("poisson.jpeg", destImage);
  228.  
  229. cvWaitKey(0);
  230.  
  231. // 後始末
  232. cvReleaseImage(&maskImage);
  233. cvReleaseImage(&srcImage);
  234. cvReleaseImage(&destImage);
  235.  
  236. return 0;
  237. }
Add Comment
Please, Sign In to add comment