码迷,mamicode.com
首页 > 其他好文 > 详细

Opencv图像识别从零到精通(13)----点线圆矩形与鼠标事件

时间:2016-07-22 10:24:32      阅读:942      评论:0      收藏:0      [点我收藏+]

标签:

            图像中不可少的元素就是点、线、圆、椭圆、矩形,多边形,同时这些也是物体的特征组成单位,在图像识别中必不可少。所以要首先去认识这个元素怎么定义和使用,同时鼠标是电脑的窗口,我们很多的处理都会用到鼠标。本文主要有下面三个部分:

      (1) 点、线、圆、椭圆、矩形的基础应用

      (2)点、线、圆、椭圆、矩形的进阶应用

      (3)鼠标事件

一、点、线、圆、椭圆、矩形的基础应用

绘制点的函数:

Point a = Point (600,600);

文字函数putText()函数

void putText( CvArr* img, const char* text, CvPoint org, const CvFont* font,CvScalar color );
  img:
  输入图像
  text:
  要显示的字符串
  org:
  第一个字母左下角的坐标
  font:
  指向字体结构的指针
  color:[1]  文本的颜色.
绘制直线

CV_EXPORTS_W void line(CV_IN_OUT Mat&img, Point pt1, Point pt2, const Scalar& color,
                     int thickness=1, intlineType=8, int shift=0);

  • img: 要绘制线段的图像。
  • pt1: 线段的起点。
  • pt2: 线段的终点。
  • color: 线段的颜色,通过一个Scalar对象定义。
  • thickness: 线条的宽度。
  • lineType: 线段的类型。可以取值8, 4, 和CV_AA 分别代表8邻接连接线,4邻接连接线和反锯齿连接线。默认值为8邻接。为了获得更好地效果可以选用CV_AA(采用了高斯滤波)。
  • shift: 坐标点小数点位数。

绘制椭圆

CV_EXPORTS_W void ellipse(CV_IN_OUTMat& img, Point center, Size axes,
                        double angle, doublestartAngle, double endAngle,
                        const Scalar&color, int thickness=1,
                        int lineType=8, intshift=0);

  • img: 要绘制椭圆的图像。
  • center: 椭圆中心点坐标。
  • axes: 椭圆位于该Size决定的矩形内。(即定义长轴和短轴)。
  • angle: 椭圆旋转角度。
  • startAngle: 椭圆开始绘制时角度。
  • endAngle: 椭圆绘制结束时角度。(若绘制一个完整的椭圆,则startAngle=0, endAngle = 360)。
  • color: 椭圆的颜色。
  • thickness: 绘制椭圆线粗。负数表示全部填充。
  • lineType,shift:同上。

绘制矩形

CV_EXPORTS_W void rectangle(CV_IN_OUTMat& img, Point pt1, Point pt2,
                          const Scalar&color, int thickness=1,
                          int lineType=8, intshift=0);

  • pt1: 矩形的左上角坐标。
  • pt2: 矩阵的右下角坐标。

绘制圆

CV_EXPORTS_W void circle(CV_IN_OUT Mat&img, Point center, int radius,
                       const Scalar& color,int thickness=1,
                       int lineType=8, int shift=0);

  • center: 圆心坐标。
  • radius: 半径。
  • 其余同上。

填充多边形

CV_EXPORTS void fillPoly(Mat& img,const Point** pts,
                         const int* npts, intncontours,
                         const Scalar&color, int lineType=8, int shift=0,
                         Point offset=Point());

pts: 多边形定点集。

npts: 多边形的顶点数目。

ncontours: 要绘制多边形的数量。

offset: 所有点轮廓的可选偏移。

#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace cv;
int main()
{

Mat src(500,500,CV_8UC3,Scalar(0,0,255));  
system("color 5F");
string words= "A simple example";  
putText( src, words, Point( src.rows/2,src.cols/4),CV_FONT_HERSHEY_COMPLEX, 1, Scalar(255, 0, 0) );  
namedWindow("显示字");
imshow("显示字",src); 
 Point center = Point(300,200);  
 int r = 50;  
circle(src,center,r,Scalar(0,0,0));  
 ellipse(src,center,Size( 250, 100 ),0,30,360,Scalar(0,0,0)); 
  Point a = Point (600,600);  
line(src,a,center,Scalar(255,0,0));  
rectangle(src,a,center,Scalar(255,0,0)); 
imshow("底板",src); 
waitKey(0);
return 0;
}

技术分享

二、点、线、圆、椭圆、矩形的进阶应用

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
#include <opencv2/imgproc/imgproc.hpp>
#define WINDOW_NAME1 "【绘制图1】"        //为窗口标题定义的宏 
#define WINDOW_NAME2 "【绘制图2】"        //为窗口标题定义的宏 
#define WINDOW_WIDTH 600//定义窗口大小的宏
void DrawEllipse( Mat img, double angle );//绘制椭圆
void DrawFilledCircle( Mat img, Point center );//绘制圆
void DrawPolygon( Mat img );//绘制多边形
void DrawLine( Mat img, Point start, Point end );//绘制线段


int main( void )
{
	Mat atomImage = Mat::zeros( WINDOW_WIDTH, WINDOW_WIDTH, CV_8UC3 );
	Mat rookImage = Mat::zeros( WINDOW_WIDTH, WINDOW_WIDTH, CV_8UC3 );

	DrawEllipse( atomImage, 90 );
	DrawEllipse( atomImage, 0 );
	DrawEllipse( atomImage, 45 );
	DrawEllipse( atomImage, -45 );

	DrawFilledCircle( atomImage, Point( WINDOW_WIDTH/2, WINDOW_WIDTH/2) );

	DrawPolygon( rookImage );
	rectangle( rookImage,
		Point( 0, 7*WINDOW_WIDTH/8 ),
		Point( WINDOW_WIDTH, WINDOW_WIDTH),
		Scalar( 0, 255, 255 ),
		-1,
		8 );
	DrawLine( rookImage, Point( 0, 15*WINDOW_WIDTH/16 ), Point( WINDOW_WIDTH, 15*WINDOW_WIDTH/16 ) );
	DrawLine( rookImage, Point( WINDOW_WIDTH/4, 7*WINDOW_WIDTH/8 ), Point( WINDOW_WIDTH/4, WINDOW_WIDTH ) );
	DrawLine( rookImage, Point( WINDOW_WIDTH/2, 7*WINDOW_WIDTH/8 ), Point( WINDOW_WIDTH/2, WINDOW_WIDTH ) );
	DrawLine( rookImage, Point( 3*WINDOW_WIDTH/4, 7*WINDOW_WIDTH/8 ), Point( 3*WINDOW_WIDTH/4, WINDOW_WIDTH ) );
	imshow( WINDOW_NAME1, atomImage );
	moveWindow( WINDOW_NAME1, 0, 200 );
	imshow( WINDOW_NAME2, rookImage );
	moveWindow( WINDOW_NAME2, WINDOW_WIDTH, 200 );
	waitKey( 0 );
	return(0);
}

void DrawEllipse( Mat img, double angle )
{
	int thickness = 2;
	int lineType = 8;

	ellipse( img,
		Point( WINDOW_WIDTH/2, WINDOW_WIDTH/2 ),
		Size( WINDOW_WIDTH/4, WINDOW_WIDTH/16 ),
		angle,
		0,
		360,
		Scalar( 255, 129, 0 ),
		thickness,
		lineType );
}

void DrawFilledCircle( Mat img, Point center )
{
	int thickness = -1;
	int lineType = 8;

	circle( img,
		center,
		WINDOW_WIDTH/32,
		Scalar( 0, 0, 255 ),
		thickness,
		lineType );
}


void DrawPolygon( Mat img )
{
	int lineType = 8;

	//创建一些点
	Point rookPoints[1][20];
	rookPoints[0][0]  = Point(    WINDOW_WIDTH/4,   7*WINDOW_WIDTH/8 );
	rookPoints[0][1]  = Point(  3*WINDOW_WIDTH/4,   7*WINDOW_WIDTH/8 );
	rookPoints[0][2]  = Point(  3*WINDOW_WIDTH/4,  13*WINDOW_WIDTH/16 );
	rookPoints[0][3]  = Point( 11*WINDOW_WIDTH/16, 13*WINDOW_WIDTH/16 );
	rookPoints[0][4]  = Point( 19*WINDOW_WIDTH/32,  3*WINDOW_WIDTH/8 );
	rookPoints[0][5]  = Point(  3*WINDOW_WIDTH/4,   3*WINDOW_WIDTH/8 );
	rookPoints[0][6]  = Point(  3*WINDOW_WIDTH/4,     WINDOW_WIDTH/8 );
	rookPoints[0][7]  = Point( 26*WINDOW_WIDTH/40,    WINDOW_WIDTH/8 );
	rookPoints[0][8]  = Point( 26*WINDOW_WIDTH/40,    WINDOW_WIDTH/4 );
	rookPoints[0][9]  = Point( 22*WINDOW_WIDTH/40,    WINDOW_WIDTH/4 );
	rookPoints[0][10] = Point( 22*WINDOW_WIDTH/40,    WINDOW_WIDTH/8 );
	rookPoints[0][11] = Point( 18*WINDOW_WIDTH/40,    WINDOW_WIDTH/8 );
	rookPoints[0][12] = Point( 18*WINDOW_WIDTH/40,    WINDOW_WIDTH/4 );
	rookPoints[0][13] = Point( 14*WINDOW_WIDTH/40,    WINDOW_WIDTH/4 );
	rookPoints[0][14] = Point( 14*WINDOW_WIDTH/40,    WINDOW_WIDTH/8 );
	rookPoints[0][15] = Point(    WINDOW_WIDTH/4,     WINDOW_WIDTH/8 );
	rookPoints[0][16] = Point(    WINDOW_WIDTH/4,   3*WINDOW_WIDTH/8 );
	rookPoints[0][17] = Point( 13*WINDOW_WIDTH/32,  3*WINDOW_WIDTH/8 );
	rookPoints[0][18] = Point(  5*WINDOW_WIDTH/16, 13*WINDOW_WIDTH/16 );
	rookPoints[0][19] = Point(    WINDOW_WIDTH/4,  13*WINDOW_WIDTH/16 );

	const Point* ppt[1] = { rookPoints[0] };
	int npt[] = { 20 };

	fillPoly( img,
		ppt,
		npt,
		1,
		Scalar( 255, 255, 255 ),
		lineType );
}

void DrawLine( Mat img, Point start, Point end )
{
	int thickness = 2;
	int lineType = 8;
	line( img,
		start,
		end,
		Scalar( 0, 0, 0 ),
		thickness,
		lineType );
}


技术分享

这只猫一定是哪个很有爱心的博主画的,很是喜欢,所以就推荐它,当然还有示例中给出的,图片是下图,不过上面那个猫更加简洁让人吸收的块,官方例子太长了

技术分享

三、鼠标事件

setMouseCallback()函数讲解:

函数原型为 void setMouseCallback(conststring& winname, MouseCallback onMouse, void* userdata = 0);

这个函数的讲解见下图:

                                                          技术分享

#include <opencv2/opencv.hpp>
using namespace cv;
#define WINDOW_NAME "【程序窗口】"      
void on_MouseHandle(int event, int x, int y, int flags, void* param);
void DrawRectangle( cv::Mat& img, cv::Rect box );
Rect g_rectangle;
bool g_bDrawingBox = false;//是否进行绘制
RNG g_rng(12345);
int main( int argc, char** argv ) 
{

	system("color 9F"); 
	g_rectangle = Rect(-1,-1,0,0);
	Mat srcImage(600, 800,CV_8UC3), tempImage;
	srcImage.copyTo(tempImage);
	g_rectangle = Rect(-1,-1,0,0);
	srcImage = Scalar::all(0);
	namedWindow( WINDOW_NAME );
        setMouseCallback(WINDOW_NAME,on_MouseHandle,(void*)&srcImage);
	while(1)
	{
		srcImage.copyTo(tempImage);
		if( g_bDrawingBox ) DrawRectangle( tempImage, g_rectangle );
		imshow( WINDOW_NAME, tempImage );
		if( waitKey( 10 ) == 27 ) 
		break;
	}
	return 0;
}

void on_MouseHandle(int event, int x, int y, int flags, void* param)
{

	Mat& image = *(cv::Mat*) param;
	switch( event)
	{
		
	case EVENT_MOUSEMOVE: 
		{
			if( g_bDrawingBox )
			{
				g_rectangle.width = x-g_rectangle.x;
				g_rectangle.height = y-g_rectangle.y;
			}
		}
		break;

		//左键按下消息
	case EVENT_LBUTTONDOWN: 
		{
			g_bDrawingBox = true;
			g_rectangle =Rect( x, y, 0, 0 );//记录起始点
		}
		break;

		//左键抬起消息
	case EVENT_LBUTTONUP: 
		{
			g_bDrawingBox = false;//置标识符为false
			//对宽和高小于0的处理
			if( g_rectangle.width < 0 )
			{
				g_rectangle.x += g_rectangle.width;
				g_rectangle.width *= -1;
			}

			if( g_rectangle.height < 0 ) 
			{
				g_rectangle.y += g_rectangle.height;
				g_rectangle.height *= -1;
			}
			//调用函数进行绘制
			DrawRectangle( image, g_rectangle );
		}
		break;

	}
}

void DrawRectangle( cv::Mat& img, cv::Rect box )
{
	cv::rectangle(img,box.tl(),box.br(),cv::Scalar(g_rng.uniform(0, 255), g_rng.uniform(0,255), g_rng.uniform(0,255)));//随机颜色
}




                                                            技术分享



Opencv图像识别从零到精通(13)----点线圆矩形与鼠标事件

标签:

原文地址:http://blog.csdn.net/qq_20823641/article/details/51991155

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!