基于opencv的符号提取源代码

来源:互联网 发布:判断素数c语言 9是素数 编辑:程序博客网 时间:2024/05/21 19:39
#include "stdio.h"#include "cv.h"#include "cxcore.h"#include "highgui.h"void main(int argc, char* argv[]){IplImage *src=cvLoadImage("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);//转化为二值图并且备份到binaryimagecvNamedWindow("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);}



用opencv2改写后代码如下:

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "cv.h"
#include "cxcore.h"
#include "highgui.h"
using namespace std;
using namespace cv;
int main()
{
Mat srcImage,binImage,tempImage;
srcImage=imread("test.jpg");//原图像
namedWindow("原图");
imshow("原图",srcImage);
cvtColor(srcImage,tempImage,CV_BGRA2GRAY);//原图转化为灰度图
threshold(tempImage,tempImage,220,255,CV_THRESH_BINARY_INV);//转化为二值图
tempImage.copyTo(binImage);//把二值图拷贝到binImage中
namedWindow("二值图");
imshow("二值图",binImage);
//Hough直线检测,采用标准霍夫变换
vector<Vec2f> lines;


HoughLines(tempImage,lines,1,CV_PI/180,190,0,0);

//绘制检测到的直线
size_t i,j;
float rho,theta;
for(i=0;i<lines.size();i++)
{
rho=lines[i][0];
theta=lines[i][1];
Point pt1,pt2;
double a=cos(theta);
double b=sin(theta);
if(fabs(b)<0.001)//fabs(b)求b的绝对值
{
pt1.x=pt2.x=cvRound(rho);
pt1.y=0;
pt2.y=srcImage.size().height;
}
else if(fabs(a)<0.001 )
{
pt1.y = pt2.y = cvRound(rho);
pt1.x = 0;
pt2.x = srcImage.size().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;
line(srcImage,pt1, pt2, Scalar(0,255,255), 1, 8 );
}
//按照theta排序
for (i = 0; i <lines.size(); i++)//冒泡排序
{
for (j = i; j <lines.size(); j++)
{


if (lines[i][1]>lines[j][1])
{
rho=lines[j][0];
lines[j][0]=lines[i][0];
lines[i][0]=rho;
theta=lines[j][1];
lines[j][1]=lines[i][1];
lines[i][1]=theta;
}
}
}
//统计水平线与竖直线的条数
int HNo=0,VNo=0;
for (i = 0; i <lines.size(); i++)
{
if (lines[i][1]==0)
{
VNo++; //竖线
}
}
HNo=lines.size()-VNo;//水平线
printf("直线的条数共计%d,水平线%d条,竖直线%d条\n",lines.size(),HNo,VNo);
//按照rho排序,先排竖直线
for (i = 0; i < VNo; i++)
{
for (j = i; j < VNo; j++)
{
if (lines[i][0]>lines[j][0])
{
rho=lines[j][0];
lines[j][0]=lines[i][0];
lines[i][0]=rho;
theta=lines[j][1];
lines[j][1]=lines[i][1];
lines[i][1]=theta;
}
}
}
//后排水平线
for (i = VNo; i <lines.size(); i++)
{
for (j = i; j <lines.size(); j++)
{


if (lines[i][0]>lines[j][0])
{
rho=lines[j][0];
lines[j][0]=lines[i][0];
lines[i][0]=rho;
theta=lines[j][1];
lines[j][1]=lines[i][1];
lines[i][1]=theta;
}
}
}
//输出排序后的结果
for( i = 0; i <lines.size(); i++ )
{
printf("直线%d:rho=%f,theta=%f\n",i,lines[i][0],lines[i][1]);
}


//逐个扫描各个矩形区域
for (i=0;i<17;i++)//代表水平线
{
for (j=0;j<5;j++)//j代表竖线
{
int x1,y1,x2,y2,reduce;
reduce=2;
x1=(int)lines[2+j][0]+reduce;
if (j==4)
{
x2=srcImage.size().width-reduce;
}
else
{
x2=(int)lines[3+j][0]-reduce;
}
y1=(int)lines[VNo+1+i][0]+reduce;
if (i==16)
{
y2=srcImage.size().height-reduce;
}
else
{
y2=(int)lines[VNo+2+i][0]-reduce;
}
int sum=0;

for (int m=x1;m<=x2;m++)//遍历矩形的像素==255?x表示列
{

for (int n=y1;n<=y2;n++)//y代表的高度,即行
{
uchar *data=binImage.ptr<uchar>(n);
//通过n取到每行的首地址
if (data[m]==255)
{
sum++;
}
}
}
//cout<<x1<<" "<<y1<<" "<<x2<<" "<<y2<<endl;//调试程序
//面积值大于50则认为存在对号
if (sum>50) //判断矩形里面的
{

int bb = rand() & 0xffffff;
rectangle(srcImage,Point(x1,y1),Point(x2,y2),Scalar(0,255,0),CV_FILLED );
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;
}


}//for循环结束


namedWindow("result");
imshow("result",srcImage);
imwrite("result.jpg",srcImage);


waitKey();
return 0;
}


0 0
原创粉丝点击