int main(int argc, const char * argv[]) { int threshold; int row,col,maxcolor; char* pgmFile="/Users/oo/Desktop/Eclipse_Projects/CS464_P1_PatternRecog/TestImages/square_and_circle_1024_1024.pgm"; int* image; //read image data into one array from pgm file image = getImage(pgmFile, &row, &col, &maxcolor); //Step 1: calculate and print the histoGram data int* histo = getHistoGram((int*)image, row*col); //Step 2: calculate the threshold value via Ostu algo. threshold = otsuThreshold(histo,maxcolor); //Step 3: convert the grey image into binary image int* binaryImage = convertToBinary((int*)image, row*col, threshold); //Step 4: connectivity analysis int* connectImage = connectAnalysis(binaryImage, row,col); //Step5: pattern analysis, can differentiate circle and square only patternAnalysis(connectImage, row, col); //release the dynamic memory allocated free(histo); free(binaryImage); free(connectImage); free(image); return 0; }
Mat Processor::Binaryzation_otsu(Mat &image) { int ThresNum1 = peak_valleyThreshold(image); int ThresNum2 = otsuThreshold(image); imwrite("C:\\Users\\43597_000\\Desktop\\roi.jpg",image); int ThresNum = (ThresNum1 + ThresNum2) / 2; // 二值化 threshold(image, image, ThresNum, 255, THRESH_BINARY); return image; }
/************************************************************************* dis_angle(float* distance,float* angle ) 描述:角度与偏移量的读取函数 输入参数: 输出参数:float* distance,float* angle *************************************************************************/ void dis_angle(float* distance,float* angle ) //通过前排巡线板标记点最大、小值与后排标记点比较,得出角度和偏移量 { u8 a,b,c,d; otsuThreshold(buffer_blue_front,&a,&b); // 前排巡线板最大值,最小值 Now.Front_Data_Min=a; Now.Front_Data_Max=b; // otsuThreshold(buffer_blue_behind,&c,&d); // 后排巡线板最大值,最小值 // Now.Behind_Data_Min=c; // Now.Behind_Data_Max=d; // if(abs(Now.Front_Data_Min-Last.Front_Data_Min)<5) //比较上一次与现在值 // { //计算角度 // *angle=atan((Now.Front_Data_Min+Now.Front_Data_Max-Now.Behind_Data_Min-Now.Behind_Data_Max)*L/2*L_distance); // //计算偏移量 // *distance=(Now.Front_Data_Min+Now.Front_Data_Max-Now.Behind_Data_Min-Now.Behind_Data_Max)/2-middle_number; // } // else // Last.Front_Data_Min=Now.Front_Data_Min; // Last.Front_Data_Max=Now.Front_Data_Max; // Last.Behind_Data_Min=Now.Behind_Data_Min; // Last.Behind_Data_Max=Now.Behind_Data_Max; }
//Main tracking Algorithm void AnalysisModule::larvaFind(uchar * img, int imWidth, int imHeight, int frameInd){ input = cv::Mat(imHeight,imWidth,CV_8UC1,NULL); input.data = img; if(output.rows != imHeight | output.cols != imWidth) output.create(imHeight,imWidth,CV_8UC1); int nextInd = (index+1)%sampleInd.size(); //for Profiling tic(); sampleInd[nextInd] = frameInd; sampleTime[nextInd] = frameInd * frameIntervalMS; //On first image, automatically determine threshold level using the Otsu method // Minimizes within group variance of thresholded classes. Should land on the best boundary between backlight and larva if(index == -1) threshold = otsuThreshold(img,imWidth*imHeight); //Can speed this up by applying to a roi bounding box a bit larger than the previous one //Simple inverted binary threshold of the image cv::threshold(input,output,threshold,255,CV_THRESH_BINARY_INV); profile[0] = toctic(); //Detect Contours in the binary image cv::findContours(output,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE); profile[1] = toctic(); //No contours detected if (contours.size() == 0) { return; } //find contour with largest perimeter length double maxLen = 0; int maxInd = -1; double cLen; for(int i=0; i<contours.size(); i++){ cLen = cv::arcLength(cv::Mat(contours[i]), false); if(cLen >= maxLen){ maxLen = cLen; maxInd = i; }; } //Check to make sure that the perimeter is a larva by simple size analysis //(larva should have a certain perimeter length at 8.1um/pixel) cLarva[nextInd] = contours[maxInd]; //calculate bounding box bBox[nextInd] = cv::boundingRect(cv::Mat(cLarva[nextInd])); profile[2] = toctic(); //Calculate fourier coefficients fourierDecompose(cLarva[nextInd],nFourier,fourier[nextInd]); centroid[nextInd] = cv::Point2f(fourier[nextInd][0][AX],fourier[nextInd][0][AY]); profile[3] = toctic(); //Reconstruct the estimated boundary fourierReconstruct(fourier[nextInd],cFit,fitRes); profile[4] = toctic(); //Calculate Curvature perimeterCurvature(cFit,curve,fitRes/8); profile[5] = toctic(); //Find head and tail based on curvature minimums (small angle = sharp region) findHeadTail(cFit,curve,headTail); head[nextInd] = headTail[0]; tail[nextInd] = headTail[1]; profile[6] = toctic(); //Calculate Skeleton skeletonCalc(cFit,skeleton,headTail,length[nextInd],neck[nextInd]); profile[7] = toctic(); //Calculate bearing and head angle to bearing bodyAngles(tailBearingAngle[nextInd], headToBodyAngle[nextInd], head[nextInd], neck[nextInd], tail[nextInd]); profile[8] = toctic(); //Capture stage position stagePos[nextInd] = cv::Point(gui->stageThread->xpos,gui->stageThread->ypos); //Keep track of entire history with a sample every 30 frames if((nextInd % 30) == 0){ fullTrack[(fullTrackInd+1)%fullTrack.size()].x = stagePos[nextInd].x/gui->stageThread->tickPerMM_X+centroid[nextInd].x*gui->camThread->umPerPixel/1000.0; fullTrack[(fullTrackInd+1)%fullTrack.size()].y = stagePos[nextInd].y/gui->stageThread->tickPerMM_Y+centroid[nextInd].y*gui->camThread->umPerPixel/1000.0; fullTrackStim[(fullTrackInd+1)%fullTrack.size()] = binStimMax; binStimMax = 0; //updated from stimThread fullTrackInd++; } //Calculate Velocities of head and tail calcVelocities(nextInd); //Spew out profiling info //for(int i=0; i<9; i++) qDebug("%d: %.4fms",i,profile[i]*1000); //qDebug("\n"); index++; };