基于opencv的符号提取源代码

#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);//转化为二值图并且备份到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);
}



用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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值