int main(int argc, char **argv) { char *picAname, *picBname, *linesfilename; FILE *picA, *picB, *linesfile; size_t pa_width = 0, pa_height = 0; int dissolvefrac; double warpfrac; unsigned char *pa, *pb, *wa, *wb, *morph; double a, b, p; long int numlines; struct lineseg *lines; long int i; long int autosize; autosize = 1L; pa_width = pa_height = 0; if (get_args(argc, argv, &picAname, &picBname, &linesfilename, &warpfrac, &dissolvefrac, &autosize, &pa_width, &pa_height) == 0 || isatty(fileno(stdout))) { fprintf(stderr, "Usage: pixmorph [-w width] [-n height] picA.pix picB.pix linesfile warpfrac dissolvefrac > out.pix\n"); return 1; } picA = fopen(picAname, "r"); if (picA == NULL) { fprintf(stderr, "pixmorph: cannot open %s\n", picAname); return 1; } picB = fopen(picBname, "r"); if (picB == NULL) { fprintf(stderr, "pixmorph: cannot open %s\n", picBname); return 1; } linesfile = fopen(linesfilename, "r"); if (linesfile == NULL) { fprintf(stderr, "pixmorph: cannot open %s\n", linesfilename); return 1; } if (warpfrac < 0.0 || warpfrac > 1.0) { fprintf(stderr, "pixmorph: warpfrac must be between 0 and 1\n"); return 1; } if (dissolvefrac < 0 || dissolvefrac > 255) { fprintf(stderr, "pixmorph: dissolvefrac must be between 0 and 1\n"); return 1; } if (autosize) { if (fb_common_file_size(&pa_width, &pa_height, argv[1], 3) == 0) { fprintf(stderr, "pixmorph: unable to autosize\n"); return 1; } } else { struct stat sb; if (stat(picAname, &sb) < 0) { perror("pixmorph: unable to stat file:"); return 1; } if (pa_width > 0) { pa_height = sb.st_size/(3*pa_width); fprintf(stderr, "width = %lu, size = %ld, so height = %lu\n", (unsigned long)pa_width, (long)sb.st_size, (unsigned long)pa_height); } else if (pa_height > 0) pa_width = sb.st_size/(3*pa_height); if (pa_width <= 0 || pa_height <= 0) { fprintf(stderr, "pixmorph: Bogus image dimensions: %lu %lu\n", (unsigned long)pa_width, (unsigned long)pa_height); return 1; } } /* Allocate memory for our bag o' pixels. */ pa = (unsigned char *)malloc(pa_width*pa_height*3); pb = (unsigned char *)malloc(pa_width*pa_height*3); wa = (unsigned char *)malloc(pa_width*pa_height*3); wb = (unsigned char *)malloc(pa_width*pa_height*3); morph = (unsigned char *)malloc(pa_width*pa_height*3); if (pa == NULL || pb == NULL || wa == NULL || wb == NULL || morph == NULL) { fprintf(stderr, "pixmorph: memory allocation failure\n"); bu_free(pa, "pa alloc from malloc"); bu_free(pb, "pb alloc from malloc"); bu_free(wa, "wa alloc from malloc"); bu_free(wb, "wb alloc from malloc"); bu_free(morph, "morph alloc from malloc"); return 1; } /* The following is our memorizing table for weight calculation. */ for (i = 0; i < MAXLEN; i++) weightlookup[i] = -1.0; fprintf(stderr, "pixmorph: Reading images and lines file.\n"); if (pix_readpixels(picA, pa_width*pa_height, pa) < pa_width*pa_height) { fprintf(stderr, "Error reading %lu pixels from %s\n", (unsigned long)pa_width*pa_height, picAname); return 1; } if (pix_readpixels(picB, pa_width*pa_height, pb) < pa_width*pa_height) { fprintf(stderr, "Error reading %lu pixels from %s\n", (unsigned long)pa_width*pa_height, picBname); return 1; } fclose(picA); fclose(picB); /* Process the lines file. */ lines_headerinfo(linesfile, &a, &b, &p, &numlines); lines = (struct lineseg *)malloc(numlines * sizeof(struct lineseg)); numlines = lines_read(linesfile, numlines, lines, pa_width, pa_height, warpfrac, p*b); fprintf(stderr, "pixmorph: %ld line segments read\n", numlines); /* Warp the images */ fprintf(stderr, "pixmorph: Warping first image into first intermediate image.\n"); warp_image(wa, pa, lines, FIRST, pa_width, pa_height, numlines, a, b); fprintf(stderr, "pixmorph: Warping second image into second intermediate image.\n"); warp_image(wb, pb, lines, LAST, pa_width, pa_height, numlines, a, b); /* Do the dissolve */ fprintf(stderr, "pixmorph: Performing cross-dissolve between first and second\n"); fprintf(stderr, "pixmorph: intermediate images.\n"); cross_dissolve(morph, wa, wb, dissolvefrac, pa_width*pa_height); /* All done. Write everything out to a file and quit. */ pix_writepixels(pa_width*pa_height, morph); fprintf(stderr, "pixmorph: Morph complete.\n"); /* System takes care of memory deallocation. */ return 0; }
void morph(const QImage& I0,const QImage& I1, const QLineF* lines0, const QLineF* lines1, int lines_num, float s, // 0.0 -> 1.0 float a,float b,float p, // parameters QImage& Idst, QVector<QLineF>& lines_dst, int show_ui) { assert(I0.size()==I1.size()); int w=I0.width(),h=I0.height(); QImage warped_I0(w,h,QImage::Format_ARGB32), warped_I1(w,h,QImage::Format_ARGB32); std::vector<CachedLine2> clines_dst, clines_0,clines_1; clines_0.reserve(lines_num);clines_1.reserve(lines_num);clines_dst.reserve(lines_num); for(int i=0;i<lines_num;++i) { clines_0.push_back(CachedLine2(lines0[i])); clines_1.push_back(CachedLine2(lines1[i])); } lines_dst.reserve(lines_num); lines_dst.clear(); // interpolate feature lines // by interpolate two endpoints // or interpolate center and direction for(int i=0;i<lines_num;++i) { CachedLine2 cline( lerp(clines_0[i].P,clines_1[i].P,s), lerp(clines_0[i].Q,clines_1[i].Q,s), true ); clines_dst.push_back(cline); lines_dst.push_back(QLineF(cline.P.x,cline.P.y,cline.Q.x,cline.Q.y)); //lines_dst.push_back(QLineF(cline.Q.x,cline.Q.y, // cline.Q.x+7.f*cline.unit_perpendicular.x, // cline.Q.y+7.f*cline.unit_perpendicular.y)); } int bytes=I0.byteCount(),bytes_line=I0.bytesPerLine(); #ifdef USE_BSGP if(show_ui&1) warp_bsgp((uchar*)I0.bits(),(uchar*)warped_I0.bits(), w,h,bytes,bytes_line, (FLine*)&clines_0[0],(FLine*)&clines_dst[0],lines_num, a,b,p); if(show_ui&2) warp_bsgp((uchar*)I1.bits(),(uchar*)warped_I1.bits(), w,h,bytes,bytes_line, (FLine*)&clines_1[0],(FLine*)&clines_dst[0],lines_num, a,b,p); #else if(show_ui&1) warp(I0,&clines_0[0],&clines_dst[0],lines_num,warped_I0,a,b,p); if(show_ui&2) warp(I1,&clines_1[0],&clines_dst[0],lines_num,warped_I1,a,b,p); //warp_incremental(I1,&clines_1[0],&clines_dst[0],lines_num,warped_I1); #endif //Idst=warped_I1;//.copy() if(show_ui==3) #ifdef USE_BSGP cross_dissolve_bsgp(warped_I0.bits(),warped_I1.bits(),warped_I0.byteCount(),s,Idst.bits()); #else cross_dissolve(warped_I0,warped_I1,s,Idst); #endif else if(show_ui&1)