五、openCV4.9.0教程 图形绘制及像素的逻辑操作

一、画直线

cvLine 3.0版本以前使用,3.0后使用line函数

功能:绘制连接两个点的线段

函数原型:void line( Arr* img, Point pt1, Point pt2, Scalar color, int thickness=1, int line_type=8, int shift=0 );

img 图像。

pt1 线段的第一个端点。

pt2 线段的第二个端点。

color 线段的颜色。

thickness 线段的粗细程度。

line_type 线段的类型。8 (or 0) - 8-connected line(8邻接)连接 线。4 - 4-connected line(4邻接)连接线。CV_AA - antialiased 线条防锯齿波。

shift 坐标点的小数点位数。

函数cvLine 在图像中的点1和点2之间画一条线段。线段被图像或感兴趣的矩形(ROI rectangle)所裁剪。对于具有整数坐标的non-antialiasing 线条,使用8-连接或者4-连接Bresenham 算法。画粗线条时结尾是圆形的。画 antialiased 线条使用高斯滤波。要指定线段颜色,用户可以使用使用宏CV_RGB( r, g, b )。

而且指定线条颜色的时候用到的宏CV_RGB(r,g,b)定义为#define CV_RGB( r, g, b ) cvScalar( (b), (g), (r), 0 ),由此可见,实际上起作用的颜色是看cvScalar中的b,g,r顺序,线段颜色就不言而喻了

二、画矩形

ranctangle函数

void Rectangle( Arr* img,Point pt1,Point pt2, Scalar color,
                  int thickness=1, int line_type=8, int shift=0 );
img  图像.
pt1  矩形的一个顶点。
pt2  矩形对角线上的另一个顶点
color 线条颜色 (RGB) 或亮度(灰度图像 )(grayscale image)。
thickness 组成矩形的线条的粗细程度。取负值时(如 CV_FILLED)函数绘制填充了色彩的矩形。
line_type 线条的类型。见cvLine的描述
shift   坐标点的小数点位数。

1)构造函数 Rect(x,y,width,height),x, y 为左上角坐标, width, height 则为长和宽。
 

三、画圆

void circle(Mat  img, Point center, int radius, Scalar color, int thickness=1, int lineType=8, int shift=0)
img为源图像

center为画圆的圆心坐标

radius为圆的半径

color为设定圆的颜色,规则根据B(蓝)G(绿)R(红)

thickness 如果是正数,表示组成圆的线条的粗细程度。否则,表示圆是否被填充

line_type 线条的类型。默认是8

shift 圆心坐标点和半径值的小数点位数

四、画椭圆

void cvEllipse( CvArr* img, CvPoint center, CvSize axes, double angle,  double start_angle, double end_angle, CvScalar color,   int thickness=1, int line_type=8, int shift=0 );
img图像。
center椭圆圆心坐标。
axes 轴的长度。
angle  偏转的角度。
start_angle圆弧起始角的角度。.
end_angle圆弧终结角的角度。
color线条的颜色。
thickness线条的粗细程度。
line_type线条的类型,见CVLINE的描述。
shift 圆心坐标点和数轴的精度。

五、旋转矩形

RotatedRect类是OpenCV的基础类,用于创建旋转矩形,下面是它的构造函数,包含旋转中心点、尺寸大小和旋转角度。

构造函数1: 

RotatedRect(const Point2f& center, const Size2f& size, float angle);
center    旋转矩形的质心
size    旋转矩形的宽度和高度
angle    顺时针方向的旋转角度。当角度为0°,90°,180°,270°等时,矩形变为右上方的矩形
构造函数2: 

RotatedRect(const Point2f& point1, const Point2f& point2, const Point2f& point3);
通过这个构造函数也可以创建旋转矩形,只需要给出三个点,但是要指定三个点的顺序。

void myCV::bittest()
{
	Mat m1 = Mat::zeros(500, 500, CV_8UC3);
	line(m1, Point(200, 50), Point(200, 150), Scalar(255, 0, 0),6, 4, 0);
	rectangle(m1, Rect(100, 100, 80, 80), Scalar(0, 255, 255), -2, LINE_8);
	ellipse(m1,Point(300,350), Size(100,50),0,0,360,Scalar(255,255,0), 1, 8);
	ellipse(m1,Point(300,350), Size(100,50),30,0,360,Scalar( 0,0,255), 1, 8);
	ellipse(m1,Point(300,350), Size(100,50),60,0,360,Scalar(255,0,0), 1, 8);
	ellipse(m1,Point(300,350), Size(100,50),90,0,360,Scalar(0,255,0), 1, 8);
	ellipse(m1,Point(300,350), Size(100,50),120,0,360,Scalar(0,255,255), 1, 8);
	ellipse(m1,Point(300,350), Size(100,50),150,0,360,Scalar(255,255,255), 1, 8);
	Mat m2 = Mat::zeros(250, 250, CV_8UC3);	 
	circle(m2, Point(100, 100), 50, Scalar(125, 125, 0), -1, 8, 0);
	rectangle(m2, Rect(150, 150, 80, 80), Scalar(255, 255,0), -2, LINE_8);
	Mat dst= Mat(size(m1),CV_8UC3)  ;//

	Scalar ss = Scalar(0, 120, 120,0);
	RotatedRect box1 = RotatedRect(Point2f(350.0,100.0), Point2f(100.0, 50.0), 30);
	ellipse(m1, box1, ss, 1, 8);

	ellipse(m1,Point(100,350), Size(100,50),0,0,240,Scalar(255,255,255), 1, 8);

	imshow("m1", m1);
	imshow("m2", m2);

	//bitwise_and (m1, m2, dst);
	//bitwise_or(m1, m2, dst);
	//bitwise_xor(m1, m2, dst);
	bitwise_not(m1,  dst);

	imshow("dst and", dst);
}

六、像素的逻辑操作

      1、 bitwise_and 是 OpenCV 中的一个函数,它的作用是对两幅图像进行逐位与操作。

使用方法如下:bitwise_and(src1, src2, dst[, mask]) → dst

src1 和 src2 是输入图像,它们必须具有相同的尺寸和类型。dst 是输出图像,它也必须具有与 src1 和 src2 相同的尺寸和类型。mask 是一个可选的掩码图像,具有与 src1 和 src2 相同的尺寸,用于指定要对哪些像素进行操作。

如果你不指定 dst 参数,则函数将创建一个与 src1 和 src2 相同的输出图像。


cv2.bitwise_and()是对二进制数据进行“与”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“与”操作,1&1=1,1&0=0,0&1=0,0&0=0

OutputArray dst  = cv2.bitwise_and(InputArray src1, InputArray src2, InputArray mask=noArray());//dst = src1 & src2

利用掩膜(mask)进行“与”操作,即掩膜图像白色区域是对需要处理图像像素的保留,黑色区域是对需要处理图像像素的剔除,其余按位操作原理类似只是效果不同而已。

       
        2、bitwise_or(m1, m2, dst);

  void bitwise_or(InputArray src1, InputArray src2, OutputArray dst, InputArray mask = noArray());

“按位或”
        3、bitwise_xor(m1, m2, dst);

 void bitwise_xor(InputArray src1, InputArray src2, OutputArray dst, InputArray mask = noArray());

      将src1和 src2每个像素的像素值按位异或,比如某位置对应两个像素值分别为:23 和 185,则输出像素值为177,因为23185的二进制分别为1011110111001,按位异或得到10101110174

void myCV::bittest()
{
	Mat m1 = Mat::zeros(250, 250, CV_8UC3);
	Mat m2 = Mat::zeros(250, 250, CV_8UC3);
	 
	Mat dst= Mat(size(m1),CV_8UC3)  ;//

	rectangle(m1, Rect(100, 100, 80, 80), Scalar(0, 255, 255), -2, LINE_8);
	rectangle(m2, Rect(150, 150, 80, 80), Scalar(255, 255,0), -2, LINE_8);

	imshow("m1", m1);
	imshow("m2", m2);

	//bitwise_and (m1, m2, dst); 
	//bitwise_or(m1, m2, dst);
	//bitwise_xor(m1, m2, dst);
	bitwise_not(m1,  dst);

	imshow("dst not", dst);
}
void yanmo(){

Mat src1 = imread("img1.png", IMREAD_GRAYSCALE);
  Mat src2 = imread("img2.png", IMREAD_GRAYSCALE);
  cv::resize(src1, src1, Size(640, 480));
  cv::resize(src2, src2, Size(640, 480));
  imshow("src1", src1);
  imshow("src2", src2);
  // 将mask中包含人头的区域像素值设为255
  Mat mask = Mat::zeros(Size(640, 480), CV_8UC1);
  mask(Rect(320, 50, 260, 310)) = 255;

  Mat dst;
  // 只对人头取反
  bitwise_not(src1, dst, mask);
  imshow("mask1", mask);
  // 将mask反转,得到新的mask
  bitwise_not(mask, mask);
  imshow("mask2", mask);
  // 将src1中人头之外的区域拷贝到dst
  src1.copyTo(dst, mask);
  imshow("dst", dst);
  waitKey();

  return 0;
}

七、取反操作注意点

        取反只有一个操作对象。bitwise_not(m1,  dst);


八、对Mat对象局部设置

        m2(Rect(200, 200, 50, 50)) =Scalar(0,0,255);

九、Rect的相关操作

rect.contains(Point(x, y));  //返回布尔变量,判断rect是否包含Point(x, y)点
 
//还可以求两个矩形的交集和并集
rect = rect1 & rect2;
rect = rect1 | rect2;
 
//还可以对矩形进行平移和缩放  
rect = rect + Point(-100, 100);	//平移,也就是左上顶点的x坐标-100,y坐标+100
rect = rect + Size(-100, 100);	//缩放,左上顶点不变,宽度-100,高度+100
 
//还可以对矩形进行对比,返回布尔变量
rect1 == rect2;
rect1 != rect2;
 
//OpenCV里貌似没有判断rect1是否在rect2里面的功能,所以自己写一个吧
bool isInside(Rect rect1, Rect rect2)
{
	return (rect1 == (rect1&rect2));
}
 
//OpenCV貌似也没有获取矩形中心点的功能,还是自己写一个
Point getCenterPoint(Rect rect)
{
	Point cpt;
	cpt.x = rect.x + cvRound(rect.width/2.0);
	cpt.y = rect.y + cvRound(rect.height/2.0);
	return cpt;
}
 
//围绕矩形中心缩放
Rect rectCenterScale(Rect rect, Size size)
{
	rect = rect + size;	
	Point pt;
	pt.x = cvRound(size.width/2.0);
	pt.y = cvRound(size.height/2.0);
	return (rect-pt);
}

        1、方法 contain(Point) 可返回改点是否在矩形内。

        2、方法 inside(Rect) 可返回该矩形是否在矩形内。

        3、交集 Rect=Rect1&Rect2

        4、并集 Rect=Rect1|Rect2

        5、 平移 RectShift=Rect+Point

        6、 缩放 RectScale=Rect+Size

  • 30
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值