测试图片:
code:
#include <opencv\cv.h> #include <opencv\highgui.h> #include <opencv\cxcore.h> #include <stdlib.h> #include <stdio.h> void main(int argc, char* argv[]) { IplImage *src=cvLoadImage("C:\\Users\\zxl\\Desktop\\test.jpg",1); IplImage *process=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1); IplImage *binaryimage=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1); cvNamedWindow("src",1); cvShowImage("src",src); cvCvtColor(src,process,CV_BGRA2GRAY);//转化为灰度图 CvMemStorage* storage = NULL; CvSeq* lines = NULL; storage = cvCreateMemStorage(0); cvThreshold(process,process,220,255,CV_THRESH_BINARY_INV); cvCopy( process,binaryimage);//转化为二值图并且备份到binaryimage cvNamedWindow("binaryimage",1); cvShowImage("binaryimage",binaryimage); //Hough直线检测,采用标准霍夫变换 lines = cvHoughLines2( process, storage, CV_HOUGH_STANDARD, 1, CV_PI/180, 190, 0, 0 ); cvSet(src,cvScalar(255,255,255));//将原图清空,绘制出检测到的直线 int i,j; float rho, theta; for( i = 0; i < lines->total; i++ ) { float* line = (float*)cvGetSeqElem(lines, i); rho = line[0]; theta = line[1]; CvPoint pt1, pt2; double a = cos(theta), b = sin(theta); if( fabs(b) < 0.001 ) { pt1.x = pt2.x = cvRound(rho); pt1.y = 0; pt2.y = src->height; } else if( fabs(a) < 0.001 ) { pt1.y = pt2.y = cvRound(rho); pt1.x = 0; pt2.x = src->width; } else { pt1.x = 0; pt1.y = cvRound(rho/b); pt2.x = cvRound(rho/a); pt2.y = 0; } int bb = rand() & 255, gg = rand() & 255, rr = rand() & 255; cvLine( src, pt1, pt2, CV_RGB(rr,gg,bb), 1, 8 ); } //按照theta排序 for (i = 0; i < lines->total; i++) { for (j = i; j < lines->total; j++) { float* line1 = (float*)cvGetSeqElem(lines, i); float* line2 = (float*)cvGetSeqElem(lines, j); if (line1[1]>line2[1]) { rho=line2[0]; theta=line2[1]; line2[0]=line1[0]; line2[1]=line1[1]; line1[0]=rho; line1[1]=theta; } } } //统计水平线与竖直线的条数 int HNo=0,VNo=0; for (i = 0; i < lines->total; i++) { float* line = (float*)cvGetSeqElem(lines, i); if (line[1]==0) { VNo++; } } HNo=lines->total-VNo; printf("直线的条数共计%d,水平线%d条,竖直线%d条\n",lines->total,HNo,VNo); //按照rho排序,先排竖直线 for (i = 0; i < VNo; i++) { for (j = i; j < VNo; j++) { float* line1 = (float*)cvGetSeqElem(lines, i); float* line2 = (float*)cvGetSeqElem(lines, j); if (line1[0]>line2[0]) { rho=line2[0]; theta=line2[1]; line2[0]=line1[0]; line2[1]=line1[1]; line1[0]=rho; line1[1]=theta; } } } //后排水平线 for (i = VNo; i < lines->total; i++) { for (j = i; j < lines->total; j++) { float* line1 = (float*)cvGetSeqElem(lines, i); float* line2 = (float*)cvGetSeqElem(lines, j); if (line1[0]>line2[0]) { rho=line2[0]; theta=line2[1]; line2[0]=line1[0]; line2[1]=line1[1]; line1[0]=rho; line1[1]=theta; } } } //输出排序后的结果 for( i = 0; i < lines->total; i++ ) { float* line = (float*)cvGetSeqElem(lines, i); printf("直线%d:rho=%f,theta=%f\n",i,line[0],line[1]); } //逐个扫描各个矩形区域 for (i=0;i<17;i++) { for (j=0;j<5;j++) { int x1,y1,x2,y2,reduce; reduce=2; float* line = (float*)cvGetSeqElem(lines,2+j); x1=(int)line[0]+reduce; if (j==4) { x2=src->width-reduce; } else { line = (float*)cvGetSeqElem(lines,3+j); x2=(int)line[0]-reduce; } line = (float*)cvGetSeqElem(lines,VNo+1+i); y1=(int)line[0]+reduce; if (i==16) { y2=src->height-reduce; } else { line = (float*)cvGetSeqElem(lines,VNo+2+i); y2=(int)line[0]-reduce; } int sum=0; for (int m=x1;m<=x2;m++) { for (int n=y1;n<=y2;n++) { if (CV_IMAGE_ELEM(binaryimage,unsigned char,n,m)==255) { sum++; } } } //面积值大于50则认为存在对号 if (sum>50) { cvSetImageROI(src,cvRect(x1,y1,x2-x1,y2-y1)); int bb = rand() & 0xffffff; cvFillImage(src,bb); cvResetImageROI(src); break; } } printf("部门%d的等次:",i+1); switch(j) { case 0: printf("好\n"); break; case 1: printf("较好\n"); break; case 2: printf("一般\n"); break; case 3: printf("差\n"); break; case 4: printf("极差\n"); break; default: printf("error\n"); break; } } cvNamedWindow( "result", 1 ); cvShowImage( "result", src); cvSaveImage("result.jpg",src); cvWaitKey(0); cvDestroyAllWindows(); cvReleaseImage(&src); cvReleaseImage(&process); cvReleaseImage(&binaryimage); }