矩形原图像见最下面。
思路是,采用L1、L2、L3和L4四条线,按照如图所示方向依次扫过图形,遇到角点停止,返回坐标。
(该方法只对部分规则的四边形适用)
问题是A和B点的识别程序通不过,请问问大家是怎么回事,该如何解决?
源代码如下:
// gangban.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include
#include
#include "highgui.h"
#include "cv.h"
#include "cxcore.h"
int _tmain(int argc, _TCHAR* argv[])
{
using namespace std;
IplImage* src = cvLoadImage("D:\\PERSONAL\\VC++\\OpenCV\\image\\gbfushi.jpg",1);//\\5.jpg
// cvNamedWindow("gbfushi",0);// 0 按窗口比例满窗口显示; 1 按原比例显示,和窗口大小无关
// cvShowImage("gbfushi",src);
//将src的RGB三个通道分别显示 测试发现B的像素差异最大
IplImage* src_b = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
IplImage* src_g = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
IplImage* src_r = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
cvSplit(src,src_b,src_g,src_r,NULL);
/******** 正式处理部分代码 B通道 灰度图 ***********/
//1 二值化
IplImage* src_gray = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);//IPL_DEPTH_8U unchar
cvThreshold(src_b,src_gray,190,255,CV_THRESH_BINARY);
// cvNamedWindow("src_gray",0);cvShowImage("src_gray",src_gray);
//2 开运算
IplImage* src_open = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
IplConvKernel* element = 0;//腐蚀结构体变量
element = cvCreateStructuringElementEx(3,3,2,2,CV_SHAPE_RECT,0);//3*3矩形 锚点(2,2 )
cvMorphologyEx(src_gray,src_open,NULL,element,1);
cvNamedWindow("src_open",0);cvShowImage("src_open",src_open);
//3 边界提取
IplImage* src_canndy = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
cvCanny(src_open,src_canndy,250,255,3);
cvNamedWindow("src_canndy",0);
cvShowImage("src_canndy",src_canndy);
//4 画内切矩形
uchar* data;//指向src_open像素值的指针
data = (uchar*)src_open->imageData;
int yy = 0,xx = 0;
CvScalar color;//B G R
color.val[0] = 0;
color.val[1] = 0;
color.val[2] = 0;
//D 点坐标获取
for(int b=0 ; bheight && 0 == data[ yy*src_canndy->width + xx]; b++)
{
for(xx=0 ; xx<=b && 0 == data[yy*src_canndy->width + xx];xx++)
yy = b - xx;
}
printf("1 D : xx = %d, yy = %d \n",xx,yy);
CvPoint pointD = cvPoint(xx,yy);
color.val[0] = 0;//B G R
color.val[1] = 128;
color.val[2] = 255;
cvCircle(src,pointD,10,color,5,8,0); //yellow
xx = 0;
yy = 0;
//C 点坐标获取
for( int b = src_canndy->width ; b>=0 && 0 == data[ yy*src_canndy->width + xx]; b-- )
{
for(xx = src_canndy->width ; xx >= b && 0 == data[ yy*src_canndy->width + xx]; xx--)
yy = xx - b;
}
printf("2 C : xx = %d, yy = %d \n",xx,yy);
CvPoint pointC = cvPoint(xx,yy);
color.val[0] = 0;//B G R
color.val[1] = 0;
color.val[2] = 255;
cvCircle(src,pointC,10,color,5,8,0); //red
xx = 0;
yy = 0;
//A 点坐标获取
for( int b = src_canndy->height ; b>=0
&& 0 == data[ yy*src_canndy->width + xx]; b-- )
{
for( xx = 0 ; xx <= src_canndy->height - b && 0 == data[ yy*src_canndy->width + xx]; xx++)
yy = xx + b;
}
printf("2 A : xx = %d, yy = %d \n",xx,yy);
CvPoint pointA = cvPoint(xx,yy);
color.val[0] = 255;//B G R
color.val[1] = 0;
color.val[2] = 0;
cvCircle(src,pointA,20,color,10,8,0); //blue
xx = 0;
yy = 0;
/* //B 点坐标获取
for( int b = src_canndy->height + src_canndy->width ; b >= src_canndy->height && 0 == data[ yy*src_canndy->width + xx]; b-- )
{
for(xx = src_canndy->width ; xx >= b - src->height && 0 == data[ yy*src_canndy->width + xx]; xx--)
yy = b - xx;
}
printf("4 B : xx = %d, yy = %d \n",xx,yy);
CvPoint pointB = cvPoint(xx,yy);
color.val[0] = 0;//B G R
color.val[1] = 255;
color.val[2] = 0;
cvCircle(src,pointB,20,color,10,8,0); //green
*/
cvNamedWindow("gbfushi",0);cvShowImage("gbfushi",src);
printf("src_open->widthStep = %d\n",src_open->widthStep);
cvWaitKey(0);
cvReleaseImage(&src);
cvReleaseImage(&src_b);cvReleaseImage(&src_g);cvReleaseImage(&src_r);
cvReleaseImage(&src_gray);
cvReleaseImage(&src_open);
cvReleaseImage(&src_canndy);
cvDestroyAllWindows();
return 0;
}