openCV实战(一):rectangle函数使用

rect类

Rect对象的定义:

typedef Rect_<int> Rect;

再看Rect_的定义:

/*!
  The 2D up-right rectangle class
  The class represents a 2D rectangle with coordinates of the specified data type.
  Normally, cv::Rect ~ cv::Rect_<int> is used.
*/
template<typename _Tp> class Rect_
{
public:
    typedef _Tp value_type;
 
    //! various constructors
    Rect_();
    Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height);
    Rect_(const Rect_& r);
    Rect_(const CvRect& r);
    Rect_(const Point_<_Tp>& org, const Size_<_Tp>& sz);
    Rect_(const Point_<_Tp>& pt1, const Point_<_Tp>& pt2);
 
    Rect_& operator = ( const Rect_& r );
    //! the top-left corner
    Point_<_Tp> tl() const;
    //! the bottom-right corner
    Point_<_Tp> br() const;
 
    //! size (width, height) of the rectangle
    Size_<_Tp> size() const;
    //! area (width*height) of the rectangle
    _Tp area() const;
 
    //! conversion to another data type
    template<typename _Tp2> operator Rect_<_Tp2>() const;
    //! conversion to the old-style CvRect
    operator CvRect() const;
 
    //! checks whether the rectangle contains the point
    bool contains(const Point_<_Tp>& pt) const;
 
    _Tp x, y, width, height; //< the top-left corner, as well as width and height of the rectangle
};

从上面的定义至少可以发现两点:

  • 类Rect_的类模板中的数据类型_Tp在Rect_中被指定为整型;
  • Rect_的构造函数可以看出,其形参列表一共有6种形式:
Rect_()// 形参列表为空,即定义一个空窗口(默认值为:x=y=width=height=0);
Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height)//定义一个左上角点坐标为(_x, _y)的_width*_height矩形窗口;
Rect_(const Rect_& r)//使用其他的Rect_对象初始化;
Rect_(const CvRect& r)//使用CvRect对象初始化;
Rect_(const Point_<_Tp>& org, const Size_<_Tp>& sz)//分别将位置坐标(_x, _y)和窗口大小(_width, _height)用Point_和Size_对象初始化;
Rect_(const Point_<_Tp>& pt1, const Point_<_Tp>& pt2)//分别将坐标位置(_x, _y)和窗口大小(_width, _height)用Point_和Point_对象初始化。

在OpenCV库中,图像像素坐标与所在行列数的对应关系为:x -> col, y -> row, width -> cols, height -> rows

Mat image = imread("C:\\Users\\Leo\\Desktop\\lena.jpg");
Rect rect1(256, 256, 128, 128);
Rect rect2(224, 224, 128, 128);
 
Mat roi1;
image(rect1).copyTo(roi1); // copy the region rect1 from the image to roi1
imshow("1", roi1);
waitKey(0);
 
Mat roi2;
image(rect2).copyTo(roi2); // copy the region rect2 from the image to roi2
imshow("2", roi2);
waitKey(0);
 
cv::Rect rect3 = rect1&rect2; // intersection of the two sets
Mat roi3;
image(rect3).copyTo(roi3);
imshow("3", roi3);
waitKey(0);
 
Rect rect4 = rect1|rect2; // union of the two sets (the minimum bounding rectangle)
Mat roi4;
image(rect4).copyTo(roi4);
imshow("4", roi4);
waitKey(0);
 
Rect rect5(10, 10, 128, 128);
roi1.copyTo(image(rect5)); // copy the region rect1 to the designated region in the image
imshow("5", image);
waitKey(0);

rectangle函数

void rectangle(InputOutputArray img, Point pt1, Point pt2,const Scalar& color, int thickness = 1, int lineType = LINE_8, int shift = 0);

简介:使用对角线的两点pt1,pt2画一个矩形轮廓或者填充矩形

@param img Image.
@param pt1 Vertex of the rectangle.
@param pt2 Vertex of the rectangle opposite to pt1 .
@param color Rectangle color or brightness (grayscale image).color 线条颜色 (RGB) 或亮度(灰度图像 )
@param thickness Thickness of lines that make up the rectangle. Negative values, like CV_FILLED ,
mean that the function has to draw a filled rectangle.thickness 组成矩形的线条的粗细程度。取负值时(如 CV_FILLED)函数绘制填充了色彩的矩形
@param lineType Type of the line.

连续绘制多个矩形


#include <iostream>
#include <opencv2/opencv.hpp>

#include "core/core.hpp"
#include "highgui/highgui.hpp"
#include "imgproc/imgproc.hpp"


//连续画矩形框
using namespace cv;
using namespace std;
//去掉以上两行代码注释之后就可以不用在下面的代码中加上cv::和std::
//cv::为OpenCV的函数库
//std::为C++的标准函数库



void OnMouseAction(int event, int x, int y, int flags, void *ustc);  //鼠标回调事件函数
Rect rect,temp;
Mat src, src1;

void draw_rec(Mat str, Mat src1);
void draw_rec1(Mat str, Mat src1);
int static times; //记录调用次数
int DrawRect();
int rec_num;

int main(int argc, char*argv[])
{
	//以下的方法如果想运行,直接把前头的注释去掉即可
	//运行代码的时候请改掉filename里的地址
	//我的opencv是安装在C盘目录下
	//一些目录地址请自行修改一下

	//DrawRect(); //在图像上画四边形
	const char* filename = "E:\\projects\\darknet-master\\build\\darknet\\x64\\data\\voc\\VOCdevkit\\VOC2007\\JPEGImages\\img1.bmp";
	src = imread(filename);
	imshow("title", src);
	rec_num = 0;
	setMouseCallback("title", OnMouseAction, 0);

	waitKey(0);

	return 0;
}
//*******************************************************************//
//鼠标回调函数

void OnMouseAction(int event, int x, int y, int flags, void *ustc)
{
	times++;
	switch (event)
	{
		//左键按下事件
	case EVENT_LBUTTONDOWN:
		//左键按下 定义起始点
		rect.x = x;
		rect.y = y;
		rect.width = 1;
		rect.height = 1;
		cout << "触发左键按下坐标为" << x << "," << y << endl;
		break;
		
		//鼠标移动事件
	case CV_EVENT_MOUSEMOVE:
		//当左键按下时根据左键起始点绘制生成的矩形
		if (flags&EVENT_FLAG_LBUTTON)
		{
			rect = Rect(Point(rect.x, rect.y), Point(x, y));
			draw_rec1(src,src1);   //鼠标移动过程中显示移动轨迹
		}
		break;
	    //左键松开事件
	case CV_EVENT_LBUTTONUP:
		if (rect.width > 1 && rect.height > 1)
		{
			
			draw_rec(src,src1);
			rec_num++;
		}
		cout << "触发左键松开坐标为" << x << "," << y << endl;
		cout << "选中区域个数为" << rec_num << endl;
	default:
		break;


	}
	//cout << "第 " << times << " 次回调鼠标事件" << endl;
	//if (event == CV_EVENT_MOUSEMOVE)
	//{
	//	cout << "触发鼠标移动事件" << endl;
	//}
	//if (event == CV_EVENT_LBUTTONDOWN)
	//{
	//	cout << "触发左键按下事件" << endl;
	//}
	//if (event == CV_EVENT_LBUTTONUP)
	//{
	//	cout << "触发左键抬起事件" << endl;
	//}
	//if (event == CV_EVENT_RBUTTONDOWN)
	//{
	//	cout << "触发右键按下事件" << endl;
	//	DrawRect(); //在图像上画四边形
	//}
	//if (event == CV_EVENT_RBUTTONUP)
	//{

	//	cout << "触发右键抬起事件" << endl;

	//}
	//if (event == CV_EVENT_LBUTTONDBLCLK)
	//{
	//	cout << "触发左键双击事件" << endl;
	//}
	//if (event == CV_EVENT_RBUTTONDBLCLK)
	//{
	//	cout << "触发右键双击事件" << endl;
	//}
}



void draw_rec(Mat src, Mat src1)
{
	src.copyTo(src1);
	rectangle(src1, rect, Scalar(0, 0, 255));
	src1.copyTo(src);
	imshow("title", src1);
	
}

void draw_rec1(Mat src, Mat src1)
{
	src.copyTo(src1);
	rectangle(src1, rect, Scalar(0, 0, 255));
	imshow("title", src1);

}

int DrawRect() {
	const char* filename = "E:\\projects\\darknet-master\\build\\darknet\\x64\\data\\voc\\VOCdevkit\\VOC2007\\JPEGImages\\img1.bmp";

	cv::Mat mat = cv::imread(filename);
	if (mat.empty()) {
		throw("Faild open file.");
	}

	cv::Point p0 = cv::Point(mat.cols / 8, mat.rows / 8);
	cv::Point p1 = cv::Point(mat.cols * 7 / 8, mat.rows * 7 / 8);
	//设定点的起始和终止坐标

	rectangle(mat, p0, p1, cv::Scalar(0, 255, 0), 5, 8);
	//画四边形的函数
	//第一个参数为画图的目标图像
	//第二个参数为画图的起始坐标
	//第三个参数为画图的终止坐标
	//第四个参数为画图的颜色

	cv::Point p2 = cv::Point(mat.cols * 2 / 8, mat.rows * 2 / 8);
	cv::Point p3 = cv::Point(mat.cols * 6 / 8, mat.rows * 6 / 8);

	rectangle(mat, p2, p3, cv::Scalar(0, 255, 255), 2, 4);
	cv::imshow("mat", mat);
	//cv::imwrite("C:\\Code\\FirstOpenCVProgramming\\DrawRect.jpg", mat);
	cv::waitKey();
	return 0;
}

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时间之里

好东西就应该拿出来大家共享

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值