图像中不可少的元素就是点、线、圆、椭圆、矩形,多边形,同时这些也是物体的特征组成单位,在图像识别中必不可少。所以要首先去认识这个元素怎么定义和使用,同时鼠标是电脑的窗口,我们很多的处理都会用到鼠标。本文主要有下面三个部分:
(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)));//随机颜色
}
图像识别算法交流 QQ群:145076161,欢迎图像识别与图像算法,共同学习与交流