Commit 43386134331dc2d345eccf97e46ac7c69ca80ba7

More work on blending.
c/azy.c
(172 / 51)
  
148148 return true;
149149}
150150
151bool azy_warp(struct position* const result_,
152 struct position const* const position,
153 CvMat const* const matrix) {
154 CvMat* vector = cvCreateMat(3, 1, CV_32F);
155 cvmSet(vector, 0, 0, position->x);
156 cvmSet(vector, 1, 0, position->y);
157 cvmSet(vector, 2, 0, 1);
158 cvMatMul(matrix, vector, vector);
159 result_->x = cvmGet(vector, 0, 0);
160 result_->y = cvmGet(vector, 1, 0);
161 cvReleaseMat(&vector);
162
163 return true;
164}
165
151166bool azy_create_scaled_image(struct colorful_image* const result_,
152167 struct colorful_image const* const image,
153168 size_t const pixels) {
231231 return size;
232232}
233233
234size_t azy_log2(size_t size) {
235 size_t result = 0;
236 while ((size /= 2) > 0)
234size_t azy_max(size_t const size,
235 size_t const another_size) {
236 if (another_size > size)
237 return another_size;
238
239 return size;
240}
241
242size_t azy_log2p(size_t size) {
243 size_t result = 1;
244 while ((size = (size + 1) / 2) > 1)
237245 ++result;
238246
239247 return result;
240248}
241249
242bool azy_create_gaussian_pyramid(struct gray_image** const result_,
243 struct gray_image const* const image) {
244 size_t const w = image->pixels->width;
245 size_t const h = image->pixels->height;
246 size_t const level_count = azy_min(azy_log2(w), azy_log2(w));
250bool azy_create_gaussian_pyramid(struct colorful_image*** const result_,
251 size_t* const height_,
252 struct colorful_image const* const image) {
253 size_t const w = (size_t )image->pixels->width;
254 size_t const h = (size_t )image->pixels->height;
255 size_t level_count = azy_min(azy_log2p(w), azy_log2p(h));
256 // This ensures the image is at least 8x8 so that CV_GAUSSIAN_5x5 can be used.
257 if (level_count < 4)
258 return false;
259 level_count -= 3;
247260
248 struct gray_image** const result = calloc(level_count, sizeof *result);
261 struct colorful_image** const result = calloc(level_count, sizeof *result);
249262 if (result == NULL)
250263 return false;
251264
252 // Here is some work to do.
265 IplImage* imagination = image->pixels;
266 CvSize size = cvGetSize(imagination);
267 int const type = cvGetElemType(imagination);
268 int const dimensions = cvGetDims(imagination, NULL);
269 result[0]->pixels = imagination;
270 for (size_t level = 1;
271 level < level_count;
272 ++level) {
273 size = cvSize((size.width + 1) / 2, (size.height + 1) / 2);
274 imagination = cvCreateImage(size, type, dimensions);
275 cvPyrDown(image->pixels, imagination, CV_GAUSSIAN_5x5);
276 result[level]->pixels = imagination;
277 }
253278
254 CvSize old_size = cvGetSize(image->pixels);
279 *result_ = result;
280 *height_ = level_count;
281
282 return true;
283}
284
285bool azy_create_laplacian_pyramid(struct colorful_image*** const result_,
286 size_t* const height_,
287 struct colorful_image const** const gaussian_pyramid,
288 size_t const height) {
289 if (height == 0)
290 return false;
291
292 size_t const level_count = height - 1;
293 if (level_count == 0)
294 return false;
295
296 struct colorful_image** const result = calloc(level_count, sizeof *result);
297 if (result == NULL)
298 return false;
299
255300 for (size_t level = 0;
256301 level < level_count;
257302 ++level) {
258 CvSize new_size = cvSize((old_size.width + 1) / 2, (old_size.height + 1) / 2);
259 IplImage* imagination = cvCreateImage(new_size, IPL_DEPTH_8U, 1);
260 cvPyrDown(image->pixels, imagination, CV_GAUSSIAN_5x5);
261 result[level] = imagination;
303 IplImage const* const base = gaussian_pyramid[level]->pixels;
304 CvSize size = cvGetSize(base);
305 int const type = cvGetElemType(base);
306 int const dimensions = cvGetDims(base, NULL);
307 IplImage* const imagination = cvCreateImage(size, type, dimensions);
308 cvPyrUp(gaussian_pyramid[level + 1]->pixels, imagination, CV_GAUSSIAN_5x5);
309 cvSub(base, imagination, imagination, NULL);
310 result[level]->pixels = imagination;
262311 }
263312
264313 *result_ = result;
314 *height_ = level_count;
265315
266316 return true;
267317}
268318
269bool azy_create_laplacian_pyramid(struct gray_image** const result_,
270 struct gray_image const* const* const gaussian_pyramid) {
319bool azy_create_reconstructed_image(struct colorful_image** const result_,
320 struct colorful_image const** const laplacian_pyramid,
321 size_t const height) {
322 // Urgh!
323
271324 return false;
272325}
273326
327bool azy_create_blent_slarp(struct colorful_image*** const result_,
328 struct colorful_image const** const black_laplacian_pyramid,
329 struct colorful_image const** const white_laplacian_pyramid,
330 struct colorful_image const** const gaussian_pyramid) {
331 // Urgh!
332
333 return false;
334}
335
274336bool azy_guess_radius(double* const result_,
275337 struct position const* const p0,
276338 struct position const* const t0,
10061006 say("| %7.4f %7.4f %7.4f |", cvmGet(hmat, 1, 0), cvmGet(hmat, 1, 1), cvmGet(hmat, 1, 2));
10071007 say("\\ %7.4f %7.4f %7.4f /", cvmGet(hmat, 2, 0), cvmGet(hmat, 2, 1), cvmGet(hmat, 2, 2));
10081008
1009 say("About to warp the images.");
1009 say("Adding annotations now.");
10101010
10111011 CvFont font;
10121012 double const scale = 1;
10131013 cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, scale, scale, 0, 2, 8);
10141014
1015 struct colorful_image eh;
1016 eh.pixels = cvCloneImage(scaled_images[left].pixels);
1015 struct colorful_image left_image;
1016 left_image.pixels = cvCloneImage(scaled_images[left].pixels);
10171017
1018 // Borrowed from earlier.
1019 CvSize size = cvGetSize(scaled_images[right].pixels);
1018 struct colorful_image right_image;
1019 right_image.pixels = cvCloneImage(scaled_images[right].pixels);
1020
1021 CvPoint origin = cvPoint(12, 36);
1022 CvScalar color = CV_RGB(128, 0, 128);
1023 cvPutText(left_image.pixels, "Reference (left)", origin, &font, color);
1024 cvPutText(right_image.pixels, "Warped (right)", origin, &font, color);
1025
1026 say("About to warp the images.");
1027
1028 // Partially borrowed from earlier.
1029 CvSize size = cvGetSize(right_image.pixels);
10201030 struct colorful_image safe;
1021 safe.pixels = cvCreateImage(cvSize(size.width, size.height * 2), IPL_DEPTH_8U, 3);
1022 CvPoint offshit = cvPoint(0, 0);
1023 cvCopyMakeBorder(scaled_images[right].pixels, safe.pixels, offshit, IPL_BORDER_CONSTANT, cvScalarAll(0));
1031 struct position const corners[] = {
1032 {.x = 0, .y = 0},
1033 {.x = size.width, .y = 0},
1034 {.x = 0, .y = size.height},
1035 {.x = size.width, .y = size.height}
1036 };
1037 struct position offsetmen = {.x = 0, .y = 0}; // Minima.
1038 struct position dimensionmen = {.x = size.width, .y = size.height}; // Maxima.
1039 for (size_t corner = 0;
1040 corner < 4;
1041 ++corner) {
1042 struct position target;
1043 azy_warp(&target, &corners[corner], hmat);
1044 if (target.x < offsetmen.x)
1045 offsetmen.x = target.x;
1046 if (target.y < offsetmen.y)
1047 offsetmen.y = target.y;
1048 if (target.x > dimensionmen.x)
1049 dimensionmen.x = target.x;
1050 if (target.y > dimensionmen.y)
1051 dimensionmen.y = target.y;
1052 }
1053 struct position const totalmen = {
1054 .x = dimensionmen.x - offsetmen.x,
1055 .y = dimensionmen.y - offsetmen.y
1056 };
1057 safe.pixels = cvCreateImage(cvSize(totalmen.x, totalmen.y), IPL_DEPTH_8U, 3);
1058 cvSet(safe.pixels, rsn, NULL);
10241059
1025 struct colorful_image thing;
1026 thing.pixels = cvCloneImage(safe.pixels);
1060 struct colorful_image sound;
1061 sound.pixels = cvCloneImage(safe.pixels);
10271062
10281063 say("(Warping sounds.)");
10291064
1030 CvPoint origin = cvPoint(12, 36);
1031 CvScalar color = CV_RGB(128, 0, 128);
1032 cvPutText(thing.pixels, "Reference (1)", origin, &font, color);
1033 cvPutText(eh.pixels, "Warped (0)", origin, &font, color);
1065 cvSetImageROI(safe.pixels, cvRect(-offsetmen.x, -offsetmen.y, size.width, size.height));
1066 cvCopy(right_image.pixels, safe.pixels, NULL);
1067 cvResetImageROI(safe.pixels);
1068
1069 cvWarpPerspective(left_image.pixels, sound.pixels, hmat, CV_INTER_LINEAR, cvScalarAll(0));
1070
10341071 /*
10351072 Pseudocode time!
10361073
1037 declare min x
1038 declare max x
1039 declare min y
1040 declare max y
1041 for each corner in image to stay still
1042 find minimum and maximum x and y
1043 for each corner in image to be warped
1044 warp corner
1045 find minimum and maximum x and y
1046 for each maximum
1047 subtract minimum
1048 rename minima to offsets
1049 rename maxima to dimensions
1050 make image with said dimensions
1051 fill it with the background color
1052 copy said image
1053 warp image to be warped into it
1054 warp the other image into the original one
10551074 create mask
10561075 fill mask with black
10571076 fill warp region with white
10581077 fill other region with half-opacity black
10591078 spline both of the images into the new image
10601079 */
1061 cvWarpPerspective(eh.pixels, safe.pixels, hmat, CV_INTER_LINEAR, cvScalarAll(0));
1062 cvAddWeighted(thing.pixels, 0.5, safe.pixels, 0.5, 0, safe.pixels);
10631080
1081 // Copied.
1082 struct colorful_image mask;
1083 mask.pixels = cvCreateImage(cvSize(totalmen.x, totalmen.y), IPL_DEPTH_8U, 3);
1084 cvSetZero(mask.pixels);
1085
1086 // Shit blending.
1087 cvAddWeighted(safe.pixels, 0.5, sound.pixels, 0.5, 0, safe.pixels);
1088 // Proper blending.
1089 /*
1090 struct colorful_image** black_gauss;
1091 struct colorful_image** white_gauss;
1092 struct colorful_image** black_lap;
1093 struct colorful_image** white_lap;
1094 struct colorful_image** cauchyan;
1095 struct colorful_image** blender;
1096 size_t gauss_height;
1097 azy_create_gaussian_pyramid(&black_gauss, &gauss_height, &safe);
1098 azy_create_gaussian_pyramid(&white_gauss, &gauss_height, &safe);
1099 size_t lap_height;
1100 azy_create_laplacian_pyramid(&black_lap, &lap_height, black_gauss, gauss_height);
1101 azy_create_laplacian_pyramid(&white_lap, &lap_height, white_gauss, gauss_height);
1102 azy_create_blent_slarp(&blender, black_lap, white_lap, cauchyan);
1103 azy_create_reconstructed_image(&safe, cauchyan, lap_height);
1104 */
1105
10641106 say("Here is a rough estimate.");
10651107 show(&safe);
1108
1109 cvReleaseMat(&hmat);
10661110 }
10671111
10681112 // Carry out fine adjustments.
c/makefile
(0 / 2)
  
4343# ../../samples/019-5/l_1397038164_82.png \
4444# #
4545 - ./azier \
46 ../../samples/061-1/l_1396438663_97.png \
4746 ../../samples/061-1/l_1396438664_12.png \
4847 ../../samples/061-1/l_1396438664_28.png \
49 ../../samples/061-1/l_1396438664_45.png \
5048# # \
5149# ../../samples/061-1/l_1396438663_97.png \
5250# ../../samples/061-1/l_1396438664_12.png \