void KeyPointsDeliverer::calcGradientImages(Mat& mouthImg) { double pseudoHuePxl = 0.0; int luminancePxl = 0; Mat rTop(mouthImg.rows, mouthImg.cols, CV_8UC1); Mat rMid(mouthImg.rows, mouthImg.cols, CV_8UC1); Mat rLow(mouthImg.rows, mouthImg.cols, CV_8UC1); for (int i = 0; i < mouthImg.rows; ++i) { for (int j = 0; j < mouthImg.cols; ++j) { pseudoHuePxl = imageProcessing.pseudoHuePxl(mouthImg, j, i); luminancePxl = imageProcessing.luminancePxl(mouthImg, j, i); rTop.at<uchar>(i,j) = (int) (pseudoHuePxl - luminancePxl); rMid.at<uchar>(i,j) = (int) (pseudoHuePxl - luminancePxl); rLow.at<uchar>(i,j) = (int) (pseudoHuePxl + luminancePxl); } } double minVal, maxVal; Mat rTopTemp; //Sobel(rTop, rTopTemp, CV_32FC1, 0, 1); Scharr(rTop, rTopTemp, CV_32FC1, 0, 1); minMaxLoc(rTopTemp, &minVal, &maxVal); rTopTemp.convertTo(rTopFinal, CV_8UC1, 255.0/(maxVal - minVal), -minVal * 255.0/(maxVal - minVal)); Mat rMidTemp; //Sobel(rMid, rMidTemp, CV_32FC1, 0, 1); Scharr(rMid, rMidTemp, CV_32FC1, 0, 1); minMaxLoc(rMidTemp, &minVal, &maxVal); rMidTemp.convertTo(rMidFinal, CV_8UC1, 255.0/(maxVal - minVal), -minVal * 255.0/(maxVal - minVal)); for (int i = 0; i < mouthImg.rows; ++i) { for (int j = 0; j < mouthImg.cols; ++j) { pseudoHuePxl = imageProcessing.pseudoHuePxl(mouthImg, j, i); rMidFinal.at<uchar>(i,j) = (int) (rMidFinal.at<uchar>(i,j) * pseudoHuePxl); } } Mat rLowTemp; //Sobel(rLow, rLowTemp, CV_32FC1, 0, 1); Scharr(rLow, rLowTemp, CV_32FC1, 0, 1); minMaxLoc(rLowTemp, &minVal, &maxVal); rLowTemp.convertTo(rLowFinal, CV_8UC1, 255.0/(maxVal - minVal), -minVal * 255.0/(maxVal - minVal)); }
/** * Calculates img gradient and hessian * * @param img source image * @param gauss times gradient gets blurred * @param hess calculate hessian or not * * @return pair of images, each representing one of gradient components */ static std::pair<Image, Image> gradient(Image const &img, unsigned gauss = 0) { Image src = img.clone(); cv::cvtColor(src, src, CV_BGR2GRAY); std::pair<Image, Image> grad; int ddepth = CV_64F; Scharr(src, grad.first, ddepth, 1, 0); Scharr(src, grad.second, ddepth, 0, 1); for (int k = 0; k < gauss; ++k) { GaussianBlur(grad.first, grad.first, cv::Size(3, 3), 0); GaussianBlur(grad.second, grad.second, cv::Size(3, 3), 0); } #ifdef PRINT_META cv::imwrite("/Users/ivan/.supp/code/snakes/grad_x.jpg", grad.first); cv::imwrite("/Users/ivan/.supp/code/snakes/grad_y.jpg", grad.second); #endif return grad; }
double Sobel(double *src,double *dst,double *edgedriction,int width,int height,int sobel_size){ //double SobelMask_x[3]={-1,-2,-1,0,0,0,1,2,1}; double *dst_x=(double *)malloc(sizeof(double)*width*height); double *dst_y=(double *)malloc(sizeof(double)*width*height); if(sobel_size==-1){ return Scharr(src, dst, edgedriction, width, height); } else if(sobel_size==3){ double SobelMask1[3]={0.25,0.5,0.25}; double SobelMask2[3]={1,0,-1}; RealConvolution(src, dst_y, SobelMask2, width, height, 1, 3 ); RealConvolution(dst_y, dst_y,SobelMask1, width, height, 3, 1); RealConvolution(src, dst_x, SobelMask1, width, height, 1, 3); RealConvolution(dst_x, dst_x, SobelMask2, width, height, 3, 1); }else if(sobel_size==5){ double SobelMask1[5]={1/16.,4/16.,6/16.,4/16.,1/16.}; double SobelMask2[5]={1/3.,2/3.,0,-2/3.,-1/3.}; RealConvolution(src, dst_x, SobelMask1, width, height, 1, 5); RealConvolution(dst_x, dst_x, SobelMask2, width, height, 5, 1); RealConvolution(src, dst_y, SobelMask2, width, height, 1, 5); RealConvolution(dst_y, dst_y, SobelMask1, width, height, 5, 1); }else if(sobel_size==7){ double SobelMask1[7]={1/64.,6/64.,15/64.,20/64.,15/64.,6/64.,1/64.}; double SobelMask2[7]={0.1,0.4,0.5,0,-0.5,-0.4,-0.1}; RealConvolution(src, dst_x, SobelMask1, width, height, 1, 7); RealConvolution(dst_x, dst_x, SobelMask2, width, height, 7, 1); RealConvolution(src, dst_y, SobelMask2, width, height, 1, 7); RealConvolution(dst_y, dst_y, SobelMask1, width, height, 7, 1); } for(int i=0;i<width*height;i++) dst_y[i]=-dst_y[i]; if(edgedriction!=NULL) getEdgeAngle(dst_x, dst_y, edgedriction, width, height); for(int j=0;j<height;j++) for(int i=0;i<width;i++){ dst[j*width+i]=abs(dst_x[j*width+i])+abs(dst_y[j*width+i]); } free(dst_x); free(dst_y); return findMatrixMax(dst,width,height,NULL); }
void getV_HBoundary(double *src,double *dst,int width,int height,double v_threshold,double a_threshold,int isVertical){ double *dst_v=(double *)malloc(sizeof(double)*width*height); double *dst_a=(double *)malloc(sizeof(double)*width*height); double *dst_d=(double *)malloc(sizeof(double)*width*height); double *temp=(double *)malloc(sizeof(double)*width*height); Scharr(src, dst_v, dst_a, width, height); getEdgeDirection(dst_a, dst_d, width, height); Non_MaxSuppression(dst_v, temp, dst_d, width, height); BoundaryDetection(temp, dst, dst_a, width, height, v_threshold, a_threshold,isVertical); free(dst_a); free(dst_v); free(dst_d); free(temp); }
Point2d InputProcessing::getEyeCenter(Mat frame, Rect eye) { //find derivatives Mat ROI = frame(eye); Mat gx, gy; GaussianBlur(ROI, ROI, Size(3, 3), 0, 0); Scharr(ROI, gx, CV_32F, 1, 0); Scharr(ROI, gy, CV_32F, 0, 1); //initialize variables Point cmaxPoint; double cmax = DBL_MIN; double c = 0; Mat cmap(gx.size(), CV_64FC1, Scalar(0)); //compute cmap field float * px, *py; unsigned char * w; double * pc; //for each vector g = gradient with origin at ROI(j,i) for (int i = 0; i < gx.rows; i++) { px = gx.ptr<float>(i); py = gy.ptr<float>(i); for (int j = 0; j < gx.cols; j++) { float plen = sqrtf(px[j] * px[j] + py[j] * py[j]); if (plen == 0) continue; px[j] /= plen; py[j] /= plen; double dxt, dyt = 0; //d^T.x, d^T.y where d is vector from c to origin of g if (plen < 300) { continue; } //for each possibl centre c = ROI(l,k) for (int k = 0; k < gx.rows; k++) { dxt = -k + i; pc = cmap.ptr<double>(k); w = ROI.ptr<unsigned char>(k); for (int l = 0; l < gx.cols; l++) { if (i == k && j == l) continue; dyt = l - j; double dlen = sqrt(dxt*dxt + dyt*dyt); double cz = px[j] * dyt / dlen - py[j] * dxt / dlen; //cross product pc[l] += cz*cz * (255 - w[l]); // inverted intensity value, since pupil is usually darker } } } } for (int i = 8; i < gx.rows - 8; i++) { pc = cmap.ptr<double>(i); for (int j = 8; j < gx.cols - 8; j++) { if (pc[j] > cmax) { cmaxPoint.x = j; cmaxPoint.y = i; cmax = pc[j]; } } } cmaxPoint += Point(eye.x, eye.y); return cmaxPoint; }
void Canny(double *src,double *dst,int width,int height,int sobel_size,double threshold1,double threshold2){ double *temp=(double *)malloc(sizeof(double)*width*height); double *edge_a=(double *)malloc(sizeof(double)*width*height);//边缘幅度 double *edge_d=(double *)malloc(sizeof(double)*width*height);//边缘方向 double *threshold_max=(double *)malloc(sizeof(double)*width*height); double *threshold_min=(double *)malloc(sizeof(double)*width*height); /********************************************************************* *step1:gaussian smooth *********************************************************************/ double gaussianmask[25]={ 2, 4, 5, 4, 2, 4, 9,12, 9, 4, 5,12,15,12, 5, 4, 9,12, 9, 4, 2, 4, 5, 4, 2}; RealConvolution(src, temp, gaussianmask, width, height, 5, 5); matrixMultreal(temp, temp, 1.0/159.0, width, height); /********************************************************************* *step2:sobel *********************************************************************/ if(sobel_size==3) Scharr(temp, edge_a, edge_d, width, height); else if(sobel_size==5||sobel_size==7) Sobel(temp, edge_a, edge_d, width, height,sobel_size); /********************************************************************* *step3:Non_MaxSuppression *********************************************************************/ getEdgeDirection(edge_d, edge_d, width, height); Non_MaxSuppression(edge_a, temp, edge_d, width, height); /********************************************************************* *step4:double threshold *********************************************************************/ Threshold(temp, threshold_max, width, height, threshold1, THRESHOLD_TYPE1); Threshold(temp, threshold_min, width, height, threshold2, THRESHOLD_TYPE1); NonZeroSetOne(threshold_max,threshold_max,width,height); NonZeroSetOne(threshold_min,threshold_min,width,height); for(int j=0;j<height;j++){ for(int i=0;i<width;i++){ if(threshold_max[j*width+i]==1.0&&threshold_min[j*width+i]!=2.0){ Position p; p.x=i; p.y=j; EdgeTrack(threshold_min, width, height, &p); } } } /********************************************************************* *step5:result *********************************************************************/ Zero(dst, width, height); for(int i=0;i<width*height;i++) if(threshold_min[i]==2.0) dst[i]=255.0; free(temp); free(threshold_max); free(threshold_min); free(edge_d); free(edge_a); }