void Arc3DModel::GenerateGradientSmoothingMask(int subsampleFactor, QImage &OriginalTexture, CharImage &mask) { CharImage gray(OriginalTexture); CharImage grad; grad.resize(gray.w,gray.h); int w=gray.w,h=gray.h; for(int x=1;x<w-1;++x) for(int y=1;y<h-1;++y) { int dx=abs(int(gray.Val(x,y))-int(gray.Val(x-1,y))) + abs(int(gray.Val(x,y))-int(gray.Val(x+1,y))); int dy=abs(int(gray.Val(x,y))-int(gray.Val(x,y-1))) + abs(int(gray.Val(x,y))-int(gray.Val(x,y+1))); grad.Val(x,y)=min(255,16*dx+dy); } // create subsampled mask int ws=gray.w/subsampleFactor, hs=gray.h/subsampleFactor; mask.resize(ws,hs); for(int x=0;x<ws;++x) for(int y=0;y<hs;++y) { unsigned char maxGrad=0; for(int si=0;si<subsampleFactor;++si) for(int sj=0;sj<subsampleFactor;++sj) maxGrad = max(maxGrad, grad.Val(x*subsampleFactor+sj,y*subsampleFactor+si)); mask.Val(x,y) = maxGrad; } CharImage mask2; mask2.resize(ws, hs); // average filter (11 x 11) int avg; int wsize = 5; for (int y = wsize; y < hs-wsize; y++) for (int x = wsize; x < ws-wsize; x++) { avg = 0; for (int yy = y - wsize; yy <= y + wsize; yy++) for (int xx = x - wsize; xx <= x + wsize; xx++) avg += mask.Val(xx, yy); mask2.Val(x, y) = min(255, avg / ((2 * wsize + 1)* (2 * wsize +1))); } mask.convertToQImage().save("tmp_testmask.jpg","jpg"); mask2.convertToQImage().save("tmp_testmaskSmooth.jpg","jpg"); // erosion filter (7 x 7) int minimum; wsize = 3; for (int y = wsize; y < hs-wsize; y++) for (int x = wsize; x < ws-wsize; x++) { minimum = mask2.Val(x, y); for (int yy = y - wsize; yy <= y + wsize; yy++) for (int xx = x - wsize; xx <= x + wsize; xx++) if (mask2.Val(xx, yy) < minimum) minimum = mask2.Val(xx, yy); mask.Val(x, y) = minimum; } grad.convertToQImage().save("tmp_test.jpg","jpg"); mask.convertToQImage().save("tmp_testmaskeroded.jpg","jpg"); }