void InitNodeBuf(Node* nodes, const unsigned char* img, int imgWidth, int imgHeight) { const bool blur = true; double px[3]; double maxD = 0; for (int y=0;y<imgHeight;y++){ for (int x=0;x<imgWidth;x++){ NODE(nodes, x, y, imgWidth).column = x; NODE(nodes, x, y, imgWidth).row = y; for (int i=0;i<4;i++){ if (blur){ // bell whistle, turn blur constant off to disable const double k[9] = {kernels[i][0], kernels[i][1], kernels[i][2], kernels[i][3], kernels[i][4], kernels[i][5], kernels[i][6], kernels[i][7], kernels[i][8]}; const double kn[25] = {k[0] / 9, (k[0] + k[1]) / 9, (k[0] + k[1] + k[2]) / 9, (k[1] + k[2]) / 9, k[2] / 9, (k[0] + k[3]) / 9, (k[0] + k[1] + k[3] + k[4]) / 9, (k[0] + k[1] + k[2] + k[3] + k[4] + k[5]) / 9, (k[1] + k[2] + k[4] + k[5]) / 9, (k[2] + k[5]) / 9, (k[0]+k[3]+k[6])/9, (k[0]+k[1]+k[3]+k[4]+k[6]+k[7])/9, (k[0]+k[1]+k[2]+k[3]+k[4]+k[5]+k[6]+k[7]+k[8])/9, (k[1]+k[2]+k[4]+k[5]+k[7]+k[8])/9, (k[2]+k[5]+k[8])/9, (k[3]+k[6])/9, (k[3]+k[4]+k[6]+k[7])/9, (k[3]+k[4]+k[5]+k[6]+k[7]+k[8])/9, (k[4]+k[5]+k[7]+k[8])/9, (k[5]+k[8])/9, k[6]/9, (k[6]+k[7])/9, (k[6]+k[7]+k[8])/9, (k[7]+k[8])/9, k[8]/9}; pixel_filter(px, x, y, img, imgWidth, imgHeight, kn, 5, 5, 1, 0); } else { pixel_filter(px, x, y, img, imgWidth, imgHeight, kernels[i], 3, 3, 1, 0); } int v = sqrt((px[0]*px[0] + px[1]*px[1] + px[2]*px[2])/3); NODE(nodes, x, y, imgWidth).linkCost[i] = v; int dx, dy; switch(i){ case 0: dx = 1; dy = 0; break; case 1: dx = 1; dy = 1; break; case 2: dx = 0; dy = 1; break; case 3: dx = -1; dy = 1; break; } if (((x+dx) > -1)&&((x+dx)<imgWidth)&&((y+dy)>-1)&&((y+dy)<imgHeight)){ NODE(nodes, x + dx, y + dy, imgWidth).linkCost[i+4] = v; } maxD = __max(maxD, v); assert(v >= px[0] * sqrt(1/3)); assert(v >= px[1] * sqrt(1/3)); assert(v >= px[2] * sqrt(1/3)); } } } for (int y=0;y<imgHeight;y++){ for (int x=0;x<imgWidth;x++){ for (int i=0;i<8;i++){ double* c = &(NODE(nodes, x, y, imgWidth).linkCost[i]); *c = (maxD - *c) * linkLengths[i]; } } } }
void image_filter(double* rsltImg, const unsigned char* origImg, const unsigned char* selection, int imgWidth, int imgHeight, const double* kernel, int knlWidth, int knlHeight, double scale, double offset) { double rsltpxl[3]; if (selection != NULL) //If non-NULL, must check every pixel { for (int y = 0; y < imgHeight; y++) { for (int x = 0; x < imgWidth; x++) { if (selection[y * imgWidth + x] == 1) { pixel_filter(rsltpxl, x, y, origImg, imgWidth, imgHeight, kernel, knlWidth, knlHeight, scale, offset); rsltImg[3 * (y * imgWidth + x) + 0] = rsltpxl[0]; rsltImg[3 * (y * imgWidth + x) + 1] = rsltpxl[1]; rsltImg[3 * (y * imgWidth + x) + 2] = rsltpxl[2]; } else { rsltImg[3 * (y * imgWidth + x) + 0] = origImg[3 * (y * imgWidth + x) + 0]; rsltImg[3 * (y * imgWidth + x) + 1] = origImg[3 * (y * imgWidth + x) + 1]; rsltImg[3 * (y * imgWidth + x) + 2] = origImg[3 * (y * imgWidth + x) + 2]; } } } } else //If NULL, can move through the whole image. { for (int y = 0; y < imgHeight; y++) { for (int x = 0; x < imgWidth; x++) { pixel_filter(rsltpxl, x, y, origImg, imgWidth, imgHeight, kernel, knlWidth, knlHeight, scale, offset); rsltImg[3 * (y * imgWidth + x) + 0] = rsltpxl[0]; rsltImg[3 * (y * imgWidth + x) + 1] = rsltpxl[1]; rsltImg[3 * (y * imgWidth + x) + 2] = rsltpxl[2]; } } } }
void image_filter(double *rsltImg, const unsigned char *origImg, const unsigned char *selection, int imgWidth, int imgHeight, const double *kernel, int knlWidth, int knlHeight, double scale, double offset) { //copy origImg to rsltImg is NOT the solution, it does nothing!, //you need to figure sth out. for (int row = 0; row < imgHeight; row++) { for (int col = 0; col < imgWidth; col++) { int index = 3 * (row * imgWidth + col); if (! selection || selection[index / 3] == 1) { double rsltPixel[] = {0 , 0, 0}; pixel_filter(rsltPixel, col, row, origImg, imgWidth, imgHeight, kernel, knlWidth, knlHeight, scale, offset); for (int color = 0; color < 3; color++) rsltImg[index + color] = rsltPixel[color]; } else for (int color = 0; color < 3; color++) rsltImg[index + color] = origImg[index + color]; } } }
void SeedSnap(int& x, int& y, unsigned char* img, int width, int height) { const double xSobel[9] = { 1.0000, 0.0000, -1.0000, 2.0000, 0.0000, -2.0000, 1.0000, 0.0000, -1.0000 }; const double ySobel[9] = { 1.0000, 2.0000, 1.0000, 0.0000, 0.0000, 0.0000, -1.0000,-2.0000,-1.0000 }; double* xGrad = new double[3 * width * height]; double* yGrad = new double[3 * width * height]; double* gradient = new double[width * height]; double maxGrad = 0.0; int idx, row, col; for (row = 0; row < height; row++) { for (col = 0; col < width; col++) { idx = 3 * (row * width + col); pixel_filter(xGrad + idx, row, col, img, width, height, xSobel, 3, 3, 8, 0); pixel_filter(yGrad + idx, row, col, img, width, height, ySobel, 3, 3, 8, 0); gradient[idx / 3] = sqrt((pow(xGrad[idx+0],2) + pow(xGrad[idx+1],2) + pow(xGrad[idx+2],2) + pow(yGrad[idx+0],2) + pow(yGrad[idx+1],2) + pow(yGrad[idx+2],2))/3); maxGrad = std::max(maxGrad, gradient[idx / 3]); } } double delta; double threshold = 0.4; bool found = false; int maxD = std::max(x,std::max(y,std::max(width-x,height-y))); int d = 0; while (++d < maxD && !found) { int i = -d - 1; while (++i <= d && !found) { int j = -d - 1; while (++j <= d && !found) { if (abs(i) == d || abs(j) == d) { row = y + j; col = x + i; if (col > 0 && row > 0 && col < width-1 && row < height-1) { idx = row * width + col; delta = maxGrad - gradient[idx]; printf("(%d,%d) %f\n", col, row, delta); if (delta/maxGrad <= threshold) { printf("Delta: %f, Max: %f\n", delta, maxGrad); printf("New (x,y): (%d,%d) %f\n", col, row, delta/maxGrad); found = true; x = col; y = row; } } } } } } // for (row = 1; row < height-1; row++) { // for (col = 1; col < width-1; col++) { // idx = row * width + col; // delta = maxGrad - gradient[idx]; // dist = sqrt(pow(row - y, 2) + pow(col - x, 2)); // cost = pow(delta/maxGrad, 2) + dist/sqrt((double)width*width + (double)height*height); // if (cost < minCost && col != x && row != y) { // minCost = cost; // newX = col; // newY = row; // printf("New (x,y): (%d,%d) %f\n", col, row, cost); // } // } // } // x = newX; // y = newY; }