OpenCV 4.9基本绘图

  • 返回:OpenCV系列文章目录(持续更新中......)

上一篇:OpenCV使用通用内部函数对代码进行矢量化

下一篇:OpenCV系列文章目录(持续更新中......)

目标

在本教程中,您将学习如何:

  • 使用 OpenCV 函数 line() 画一条线
  • 使用 OpenCV 函数 ellipse()绘制椭圆
  • 使用 OpenCV 函数 rectangle()绘制矩形
  • 使用 OpenCV 函数 circle() 画一个圆
  • 使用 OpenCV 函数 fillPoly()绘制填充多边形

OpenCV理论

在本教程中,我们将大量使用两种结构:cv::P oint 和 cv::Scalar :

它表示一个二维点,由其图像坐标 \(x\) 和 \(y\) 指定。我们可以将其定义为:

C++:

Point pt;
pt.x = 10;
pt.y = 8;

 Java:

Point pt = new Point();
pt.x = 10;
pt.y = 8;

or

C++:

Point pt = Point(10, 8);

 Java: 

Point pt = new Point(10, 8);

标量

  • 表示一个 4 元素向量。Scalar 类型在 OpenCV 中广泛用于传递像素值。
  • 在本教程中,我们将广泛使用它来表示 BGR 颜色值(3 个参数)。如果不打算使用最后一个参数,则无需定义它。
  • 让我们看一个例子,如果我们被要求一个颜色参数,我们给出:
  • Scalar( a, b, c )
    我们将定义一个 BGR 颜色,例如:蓝色 = a绿色 = b 和红色 = c

代码
此代码位于 OpenCV 示例文件夹中。否则你可以从这里下载

C++:

#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
 
#define w 400
 
using namespace cv;
 
void MyEllipse( Mat img, double angle );
void MyFilledCircle( Mat img, Point center );
void MyPolygon( Mat img );
void MyLine( Mat img, Point start, Point end );
 
int main( void ){
 
 char atom_window[] = "Drawing 1: Atom";
 char rook_window[] = "Drawing 2: Rook";
 
 Mat atom_image = Mat::zeros( w, w, CV_8UC3 );
 Mat rook_image = Mat::zeros( w, w, CV_8UC3 );
 
 
 MyEllipse( atom_image, 90 );
 MyEllipse( atom_image, 0 );
 MyEllipse( atom_image, 45 );
 MyEllipse( atom_image, -45 );
 
 MyFilledCircle( atom_image, Point( w/2, w/2) );
 
 
 MyPolygon( rook_image );
 
 rectangle( rook_image,
 Point( 0, 7*w/8 ),
 Point( w, w),
 Scalar( 0, 255, 255 ),
 FILLED,
 LINE_8 );
 
 MyLine( rook_image, Point( 0, 15*w/16 ), Point( w, 15*w/16 ) );
 MyLine( rook_image, Point( w/4, 7*w/8 ), Point( w/4, w ) );
 MyLine( rook_image, Point( w/2, 7*w/8 ), Point( w/2, w ) );
 MyLine( rook_image, Point( 3*w/4, 7*w/8 ), Point( 3*w/4, w ) );
 
 imshow( atom_window, atom_image );
 moveWindow( atom_window, 0, 200 );
 imshow( rook_window, rook_image );
 moveWindow( rook_window, w, 200 );
 
 waitKey( 0 );
 return(0);
}
 
 
void MyEllipse( Mat img, double angle )
{
 int thickness = 2;
 int lineType = 8;
 
 ellipse( img,
 Point( w/2, w/2 ),
 Size( w/4, w/16 ),
 angle,
 0,
 360,
 Scalar( 255, 0, 0 ),
 thickness,
 lineType );
}
 
void MyFilledCircle( Mat img, Point center )
{
 circle( img,
 center,
 w/32,
 Scalar( 0, 0, 255 ),
 FILLED,
 LINE_8 );
}
 
void MyPolygon( Mat img )
{
 int lineType = LINE_8;
 
 Point rook_points[1][20];
 rook_points[0][0] = Point( w/4, 7*w/8 );
 rook_points[0][1] = Point( 3*w/4, 7*w/8 );
 rook_points[0][2] = Point( 3*w/4, 13*w/16 );
 rook_points[0][3] = Point( 11*w/16, 13*w/16 );
 rook_points[0][4] = Point( 19*w/32, 3*w/8 );
 rook_points[0][5] = Point( 3*w/4, 3*w/8 );
 rook_points[0][6] = Point( 3*w/4, w/8 );
 rook_points[0][7] = Point( 26*w/40, w/8 );
 rook_points[0][8] = Point( 26*w/40, w/4 );
 rook_points[0][9] = Point( 22*w/40, w/4 );
 rook_points[0][10] = Point( 22*w/40, w/8 );
 rook_points[0][11] = Point( 18*w/40, w/8 );
 rook_points[0][12] = Point( 18*w/40, w/4 );
 rook_points[0][13] = Point( 14*w/40, w/4 );
 rook_points[0][14] = Point( 14*w/40, w/8 );
 rook_points[0][15] = Point( w/4, w/8 );
 rook_points[0][16] = Point( w/4, 3*w/8 );
 rook_points[0][17] = Point( 13*w/32, 3*w/8 );
 rook_points[0][18] = Point( 5*w/16, 13*w/16 );
 rook_points[0][19] = Point( w/4, 13*w/16 );
 
 const Point* ppt[1] = { rook_points[0] };
 int npt[] = { 20 };
 
 fillPoly( img,
 ppt,
 npt,
 1,
 Scalar( 255, 255, 255 ),
 lineType );
}
 
void MyLine( Mat img, Point start, Point end )
{
 int thickness = 2;
 int lineType = LINE_8;
 
 line( img,
 start,
 end,
 Scalar( 0, 0, 0 ),
 thickness,
 lineType );
}

Java:

import org.opencv.core.*;
import org.opencv.core.Point;
import org.opencv.highgui.HighGui;
import org.opencv.imgproc.Imgproc;
 
import java.util.*;
import java.util.List;
 
class GeometricDrawingRun{
 
 private static final int W = 400;
 
 public void run(){
 String atom_window = "Drawing 1: Atom";
 String rook_window = "Drawing 2: Rook";
 
 Mat atom_image = Mat.zeros( W, W, CvType.CV_8UC3 );
 Mat rook_image = Mat.zeros( W, W, CvType.CV_8UC3 );
 
 MyEllipse( atom_image, 90.0 );
 MyEllipse( atom_image, 0.0 );
 MyEllipse( atom_image, 45.0 );
 MyEllipse( atom_image, -45.0 );
 
 MyFilledCircle( atom_image, new Point( W/2, W/2) );
 
 MyPolygon( rook_image );
 
 Imgproc.rectangle( rook_image,
 new Point( 0, 7*W/8 ),
 new Point( W, W),
 new Scalar( 0, 255, 255 ),
 -1,
 8,
 0 );
 
 MyLine( rook_image, new Point( 0, 15*W/16 ), new Point( W, 15*W/16 ) );
 MyLine( rook_image, new Point( W/4, 7*W/8 ), new Point( W/4, W ) );
 MyLine( rook_image, new Point( W/2, 7*W/8 ), new Point( W/2, W ) );
 MyLine( rook_image, new Point( 3*W/4, 7*W/8 ), new Point( 3*W/4, W ) );
 
 HighGui.imshow( atom_window, atom_image );
 HighGui.moveWindow( atom_window, 0, 200 );
 HighGui.imshow( rook_window, rook_image );
 HighGui.moveWindow( rook_window, W, 200 );
 
 HighGui.waitKey( 0 );
 System.exit(0);
 }
 
 
 private void MyEllipse( Mat img, double angle ) {
 int thickness = 2;
 int lineType = 8;
 int shift = 0;
 
 Imgproc.ellipse( img,
 new Point( W/2, W/2 ),
 new Size( W/4, W/16 ),
 angle,
 0.0,
 360.0,
 new Scalar( 255, 0, 0 ),
 thickness,
 lineType,
 shift );
 }
 
 private void MyFilledCircle( Mat img, Point center ) {
 int thickness = -1;
 int lineType = 8;
 int shift = 0;
 
 Imgproc.circle( img,
 center,
 W/32,
 new Scalar( 0, 0, 255 ),
 thickness,
 lineType,
 shift );
 }
 
 private void MyPolygon( Mat img ) {
 int lineType = 8;
 int shift = 0;
 
 Point[] rook_points = new Point[20];
 rook_points[0] = new Point( W/4, 7*W/8 );
 rook_points[1] = new Point( 3*W/4, 7*W/8 );
 rook_points[2] = new Point( 3*W/4, 13*W/16 );
 rook_points[3] = new Point( 11*W/16, 13*W/16 );
 rook_points[4] = new Point( 19*W/32, 3*W/8 );
 rook_points[5] = new Point( 3*W/4, 3*W/8 );
 rook_points[6] = new Point( 3*W/4, W/8 );
 rook_points[7] = new Point( 26*W/40, W/8 );
 rook_points[8] = new Point( 26*W/40, W/4 );
 rook_points[9] = new Point( 22*W/40, W/4 );
 rook_points[10] = new Point( 22*W/40, W/8 );
 rook_points[11] = new Point( 18*W/40, W/8 );
 rook_points[12] = new Point( 18*W/40, W/4 );
 rook_points[13] = new Point( 14*W/40, W/4 );
 rook_points[14] = new Point( 14*W/40, W/8 );
 rook_points[15] = new Point( W/4, W/8 );
 rook_points[16] = new Point( W/4, 3*W/8 );
 rook_points[17] = new Point( 13*W/32, 3*W/8 );
 rook_points[18] = new Point( 5*W/16, 13*W/16 );
 rook_points[19] = new Point( W/4, 13*W/16 );
 
 MatOfPoint matPt = new MatOfPoint();
 matPt.fromArray(rook_points);
 
 List<MatOfPoint> ppt = new ArrayList<MatOfPoint>();
 ppt.add(matPt);
 
 Imgproc.fillPoly(img,
 ppt,
 new Scalar( 255, 255, 255 ),
 lineType,
 shift,
 new Point(0,0) );
 }
 
 private void MyLine( Mat img, Point start, Point end ) {
 int thickness = 2;
 int lineType = 8;
 int shift = 0;
 
 Imgproc.line( img,
 start,
 end,
 new Scalar( 0, 0, 0 ),
 thickness,
 lineType,
 shift );
 }
}
 
public class BasicGeometricDrawing {
 public static void main(String[] args) {
 // Load the native library.
 System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
 new GeometricDrawingRun().run();
 }
}

Python :

import cv2 as cv
import numpy as np
 
W = 400
 
def my_ellipse(img, angle):
 thickness = 2
 line_type = 8
 
 cv.ellipse(img,
 (W // 2, W // 2),
 (W // 4, W // 16),
 angle,
 0,
 360,
 (255, 0, 0),
 thickness,
 line_type)
 
def my_filled_circle(img, center):
 thickness = -1
 line_type = 8
 
 cv.circle(img,
 center,
 W // 32,
 (0, 0, 255),
 thickness,
 line_type)
 
def my_polygon(img):
 line_type = 8
 
 # Create some points
 ppt = np.array([[W / 4, 7 * W / 8], [3 * W / 4, 7 * W / 8],
 [3 * W / 4, 13 * W / 16], [11 * W / 16, 13 * W / 16],
 [19 * W / 32, 3 * W / 8], [3 * W / 4, 3 * W / 8],
 [3 * W / 4, W / 8], [26 * W / 40, W / 8],
 [26 * W / 40, W / 4], [22 * W / 40, W / 4],
 [22 * W / 40, W / 8], [18 * W / 40, W / 8],
 [18 * W / 40, W / 4], [14 * W / 40, W / 4],
 [14 * W / 40, W / 8], [W / 4, W / 8],
 [W / 4, 3 * W / 8], [13 * W / 32, 3 * W / 8],
 [5 * W / 16, 13 * W / 16], [W / 4, 13 * W / 16]], np.int32)
 ppt = ppt.reshape((-1, 1, 2))
 cv.fillPoly(img, [ppt], (255, 255, 255), line_type)
 # Only drawind the lines would be:
 # cv.polylines(img, [ppt], True, (255, 0, 255), line_type)
 
def my_line(img, start, end):
 thickness = 2
 line_type = 8
 
 cv.line(img,
 start,
 end,
 (0, 0, 0),
 thickness,
 line_type)
 
atom_window = "Drawing 1: Atom"
rook_window = "Drawing 2: Rook"
 
# Create black empty images
size = W, W, 3
atom_image = np.zeros(size, dtype=np.uint8)
rook_image = np.zeros(size, dtype=np.uint8)
 
 
# 1.a. Creating ellipses
my_ellipse(atom_image, 90)
my_ellipse(atom_image, 0)
my_ellipse(atom_image, 45)
my_ellipse(atom_image, -45)
 
# 1.b. Creating circles
my_filled_circle(atom_image, (W // 2, W // 2))
 
 
# 2. Draw a rook
# ------------------
# 2.a. Create a convex polygon
my_polygon(rook_image)
 
cv.rectangle(rook_image,
 (0, 7 * W // 8),
 (W, W),
 (0, 255, 255),
 -1,
 8)
 
 
# 2.c. Create a few lines
my_line(rook_image, (0, 15 * W // 16), (W, 15 * W // 16))
my_line(rook_image, (W // 4, 7 * W // 8), (W // 4, W))
my_line(rook_image, (W // 2, 7 * W // 8), (W // 2, W))
my_line(rook_image, (3 * W // 4, 7 * W // 8), (3 * W // 4, W))
 
cv.imshow(atom_window, atom_image)
cv.moveWindow(atom_window, 0, 200)
cv.imshow(rook_window, rook_image)
cv.moveWindow(rook_window, W, 200)
 
cv.waitKey(0)
cv.destroyAllWindows()

解释

由于我们计划绘制两个示例(一个原子和一个车),我们必须创建两个图像和两个窗口来显示它们。

 C++:

 char atom_window[] = "Drawing 1: Atom";
 char rook_window[] = "Drawing 2: Rook";
 
 Mat atom_image = Mat::zeros( w, w, CV_8UC3 );
 Mat rook_image = Mat::zeros( w, w, CV_8UC3 );

Java:

String atom_window = "Drawing 1: Atom";
 String rook_window = "Drawing 2: Rook"; 
 Mat atom_image = Mat.zeros( W, W, CvType.CV_8UC3 );
 Mat rook_image = Mat.zeros( W, W, CvType.CV_8UC3 );

Python:  

# Windows names
atom_window = "Drawing 1: Atom"
rook_window = "Drawing 2: Rook"
 
# Create black empty images
size = W, W, 3
atom_image = np.zeros(size, dtype=np.uint8)
rook_image = np.zeros(size, dtype=np.uint8)

我们创建了函数来绘制不同的几何形状。例如,为了绘制原子,我们使用了 MyEllipse 和 MyFilledCircle

 MyEllipse( atom_image, 90 );
 MyEllipse( atom_image, 0 );
 MyEllipse( atom_image, 45 );
 MyEllipse( atom_image, -45 );
 
 MyFilledCircle( atom_image, Point( w/2, w/2) );

Java:

 
 MyEllipse( atom_image, 90.0 );
 MyEllipse( atom_image, 0.0 );
 MyEllipse( atom_image, 45.0 );
 MyEllipse( atom_image, -45.0 );
 
 MyFilledCircle( atom_image, new Point( W/2, W/2) );

Python: 

# 1. Draw a simple atom:
# -----------------------
 
# 1.a. Creating ellipses
my_ellipse(atom_image, 90)
my_ellipse(atom_image, 0)
my_ellipse(atom_image, 45)
my_ellipse(atom_image, -45)
 
# 1.b. Creating circles
my_filled_circle(atom_image, (W // 2, W // 2))

为了绘制车,我们使用了 MyLine矩形和 MyPolygon

 MyPolygon( rook_image );
 
 rectangle( rook_image,
 Point( 0, 7*w/8 ),
 Point( w, w),
 Scalar( 0, 255, 255 ),
 FILLED,
 LINE_8 );
 
 MyLine( rook_image, Point( 0, 15*w/16 ), Point( w, 15*w/16 ) );
 MyLine( rook_image, Point( w/4, 7*w/8 ), Point( w/4, w ) );
 MyLine( rook_image, Point( w/2, 7*w/8 ), Point( w/2, w ) );
 MyLine( rook_image, Point( 3*w/4, 7*w/8 ), Point( 3*w/4, w ) );

Java:

 
 MyPolygon( rook_image );
 
 Imgproc.rectangle( rook_image,
 new Point( 0, 7*W/8 ),
 new Point( W, W),
 new Scalar( 0, 255, 255 ),
 -1,
 8,
 0 );
 
 MyLine( rook_image, new Point( 0, 15*W/16 ), new Point( W, 15*W/16 ) );
 MyLine( rook_image, new Point( W/4, 7*W/8 ), new Point( W/4, W ) );
 MyLine( rook_image, new Point( W/2, 7*W/8 ), new Point( W/2, W ) );
 MyLine( rook_image, new Point( 3*W/4, 7*W/8 ), new Point( 3*W/4, W ) );

Python: 

# 2. Draw a rook
# ------------------
# 2.a. Create a convex polygon
my_polygon(rook_image)
 
cv.rectangle(rook_image,
 (0, 7 * W // 8),
 (W, W),
 (0, 255, 255),
 -1,
 8) 
 
# 2.c. Create a few lines
my_line(rook_image, (0, 15 * W // 16), (W, 15 * W // 16))
my_line(rook_image, (W // 4, 7 * W // 8), (W // 4, W))
my_line(rook_image, (W // 2, 7 * W // 8), (W // 2, W))
my_line(rook_image, (3 * W // 4, 7 * W // 8), (3 * W // 4, W))

让我们检查一下这些函数中的每一个都包含什么:

我的线条:
void MyLine( Mat img, Point start, Point end )
{
 int thickness = 2;
 int lineType = LINE_8;
 
 line( img,
 start,
 end,
 Scalar( 0, 0, 0 ),
 thickness,
 lineType );
}

Java:

 private void MyLine( Mat img, Point start, Point end ) {
 int thickness = 2;
 int lineType = 8;
 int shift = 0;
 
 Imgproc.line( img,
 start,
 end,
 new Scalar( 0, 0, 0 ),
 thickness,
 lineType,
 shift );
 }

Python: 

def my_line(img, start, end):
 thickness = 2
 line_type = 8
 
 cv.line(img,
 start,
 end,
 (0, 0, 0),
 thickness,
 line_type)
  • 正如我们所看到的,MyLine 只需调用函数 line() ,它执行以下操作:
    • 从点起点到点终点画一条线
    • 该线显示在图像 img 中
    • 线条颜色由 ( 0, 0, 0 ) 定义,它是与黑色相对应的 RGB 值
    • 线条粗细设置为粗细(在本例中为 2)
    • 该线是 8 连接的线 (lineType = 8)
MyEllipse(椭圆)
void MyEllipse( Mat img, double angle )
{
 int thickness = 2;
 int lineType = 8;
 
 ellipse( img,
 Point( w/2, w/2 ),
 Size( w/4, w/16 ),
 angle,
 0,
 360,
 Scalar( 255, 0, 0 ),
 thickness,
 lineType );
}

Java:

 private void MyEllipse( Mat img, double angle ) {
 int thickness = 2;
 int lineType = 8;
 int shift = 0;
 
 Imgproc.ellipse( img,
 new Point( W/2, W/2 ),
 new Size( W/4, W/16 ),
 angle,
 0.0,
 360.0,
 new Scalar( 255, 0, 0 ),
 thickness,
 lineType,
 shift );
 }

Python: 

def my_ellipse(img, angle):
 thickness = 2
 line_type = 8
 
 cv.ellipse(img,
 (W // 2, W // 2),
 (W // 4, W // 16),
 angle,
 0,
 360,
 (255, 0, 0),
 thickness,
 line_type)
  • 从上面的代码中,我们可以观察到函数 ellipse() 绘制一个椭圆,使得:
    • 椭圆显示在图像 img 中
    • 椭圆中心位于点 (w/2, w/2) 中,并封闭在大小为 (w/4, w/16) 的盒子中
    • 椭圆是旋转角度度数
    • 椭圆在 0 到 360 度之间延伸一条弧线
    • 图形的颜色将是 ( 255, 0, 0 ),表示 BGR 值中的蓝色。
    • 椭圆的厚度为 2。
MyFilledCircle(圆)
void MyFilledCircle( Mat img, Point center )
{
 circle( img,
 center,
 w/32,
 Scalar( 0, 0, 255 ),
 FILLED,
 LINE_8 );
}

Java:

 private void MyFilledCircle( Mat img, Point center ) {
 int thickness = -1;
 int lineType = 8;
 int shift = 0;
 
 Imgproc.circle( img,
 center,
 W/32,
 new Scalar( 0, 0, 255 ),
 thickness,
 lineType,
 shift );
 }

Python: 

def my_filled_circle(img, center):
 thickness = -1
 line_type = 8
 
 cv.circle(img,
 center,
 W // 32,
 (0, 0, 255),
 thickness,
 line_type)
  • 与椭圆函数类似,我们可以观察到 circle 接收为参数:
    • 将显示圆圈的图像(img)
    • 圆的中心表示为点中心
    • 圆的半径:w/32
    • 圆圈的颜色:( 0, 0, 255 ) 在 BGR 中表示红色
    • 由于厚度 = -1,因此圆将被绘制填充。
MyPolygon
void MyPolygon( Mat img )
{
 int lineType = LINE_8;
 
 Point rook_points[1][20];
 rook_points[0][0] = Point( w/4, 7*w/8 );
 rook_points[0][1] = Point( 3*w/4, 7*w/8 );
 rook_points[0][2] = Point( 3*w/4, 13*w/16 );
 rook_points[0][3] = Point( 11*w/16, 13*w/16 );
 rook_points[0][4] = Point( 19*w/32, 3*w/8 );
 rook_points[0][5] = Point( 3*w/4, 3*w/8 );
 rook_points[0][6] = Point( 3*w/4, w/8 );
 rook_points[0][7] = Point( 26*w/40, w/8 );
 rook_points[0][8] = Point( 26*w/40, w/4 );
 rook_points[0][9] = Point( 22*w/40, w/4 );
 rook_points[0][10] = Point( 22*w/40, w/8 );
 rook_points[0][11] = Point( 18*w/40, w/8 );
 rook_points[0][12] = Point( 18*w/40, w/4 );
 rook_points[0][13] = Point( 14*w/40, w/4 );
 rook_points[0][14] = Point( 14*w/40, w/8 );
 rook_points[0][15] = Point( w/4, w/8 );
 rook_points[0][16] = Point( w/4, 3*w/8 );
 rook_points[0][17] = Point( 13*w/32, 3*w/8 );
 rook_points[0][18] = Point( 5*w/16, 13*w/16 );
 rook_points[0][19] = Point( w/4, 13*w/16 );
 
 const Point* ppt[1] = { rook_points[0] };
 int npt[] = { 20 };
 
 fillPoly( img,
 ppt,
 npt,
 1,
 Scalar( 255, 255, 255 ),
 lineType );
}

Java:

 private void MyPolygon( Mat img ) {
 int lineType = 8;
 int shift = 0;
 
 Point[] rook_points = new Point[20];
 rook_points[0] = new Point( W/4, 7*W/8 );
 rook_points[1] = new Point( 3*W/4, 7*W/8 );
 rook_points[2] = new Point( 3*W/4, 13*W/16 );
 rook_points[3] = new Point( 11*W/16, 13*W/16 );
 rook_points[4] = new Point( 19*W/32, 3*W/8 );
 rook_points[5] = new Point( 3*W/4, 3*W/8 );
 rook_points[6] = new Point( 3*W/4, W/8 );
 rook_points[7] = new Point( 26*W/40, W/8 );
 rook_points[8] = new Point( 26*W/40, W/4 );
 rook_points[9] = new Point( 22*W/40, W/4 );
 rook_points[10] = new Point( 22*W/40, W/8 );
 rook_points[11] = new Point( 18*W/40, W/8 );
 rook_points[12] = new Point( 18*W/40, W/4 );
 rook_points[13] = new Point( 14*W/40, W/4 );
 rook_points[14] = new Point( 14*W/40, W/8 );
 rook_points[15] = new Point( W/4, W/8 );
 rook_points[16] = new Point( W/4, 3*W/8 );
 rook_points[17] = new Point( 13*W/32, 3*W/8 );
 rook_points[18] = new Point( 5*W/16, 13*W/16 );
 rook_points[19] = new Point( W/4, 13*W/16 );
 
 MatOfPoint matPt = new MatOfPoint();
 matPt.fromArray(rook_points);
 
 List<MatOfPoint> ppt = new ArrayList<MatOfPoint>();
 ppt.add(matPt);
 
 Imgproc.fillPoly(img,
 ppt,
 new Scalar( 255, 255, 255 ),
 lineType,
 shift,
 new Point(0,0) );
 }

Python: 

def my_polygon(img):
 line_type = 8
 
 # Create some points
 ppt = np.array([[W / 4, 7 * W / 8], [3 * W / 4, 7 * W / 8],
 [3 * W / 4, 13 * W / 16], [11 * W / 16, 13 * W / 16],
 [19 * W / 32, 3 * W / 8], [3 * W / 4, 3 * W / 8],
 [3 * W / 4, W / 8], [26 * W / 40, W / 8],
 [26 * W / 40, W / 4], [22 * W / 40, W / 4],
 [22 * W / 40, W / 8], [18 * W / 40, W / 8],
 [18 * W / 40, W / 4], [14 * W / 40, W / 4],
 [14 * W / 40, W / 8], [W / 4, W / 8],
 [W / 4, 3 * W / 8], [13 * W / 32, 3 * W / 8],
 [5 * W / 16, 13 * W / 16], [W / 4, 13 * W / 16]], np.int32)
 ppt = ppt.reshape((-1, 1, 2))
 cv.fillPoly(img, [ppt], (255, 255, 255), line_type)
 # Only drawind the lines would be:
 # cv.polylines(img, [ppt], True, (255, 0, 255), line_type)
  • 为了绘制一个填充的多边形,我们使用函数 fillPoly() 。我们注意到:
    • 多边形将在 img 上绘制
    • 多边形的顶点是 ppt 中的点集
    • 多边形的颜色由 ( 255, 255, 255 ) 定义,这是白色的 BGR 值
矩形
 rectangle( rook_image,
 Point( 0, 7*w/8 ),
 Point( w, w),
 Scalar( 0, 255, 255 ),
 FILLED,
 LINE_8 );

Java:

 Imgproc.rectangle( rook_image,
 new Point( 0, 7*W/8 ),
 new Point( W, W),
 new Scalar( 0, 255, 255 ),
 -1,
 8,
 0 );

Python:

 

# 2.b. Creating rectangles
cv.rectangle(rook_image,
 (0, 7 * W // 8),
 (W, W),
 (0, 255, 255),
 -1,
 8)
  • 最后,我们有了cv::rectangle函数(我们没有为这个家伙创建一个特殊函数)。我们注意到:
    • 矩形将绘制在rook_image
    • 矩形的两个相对顶点由 ( 0, 7*w/8 ) 和 ( w, w ) 定义
    • 矩形的颜色由 ( 0, 255, 255 ) 给出,它是黄色的 BGR 值
    • 由于厚度值由 FILLED (-1) 给出,因此矩形将被填充。

结果

编译和运行程序应该会得到这样的结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/511620.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何对Webpack进行优化

目录 1.优化-提取css代码 1.1. 插件 mini-css-extract-plugin 1.2. 步骤&#xff1a; 1.3. 注意 1.4. 好处 1.5. 练习 2. 优化-css代码提取后压缩 2.1. 问题引入 2.2. 解决 2.3. 步骤 3. Webpack打包less代码 3.1. 加载器 less-loader 3.2. 步骤 3.3. 注意&#xf…

【Redis 知识储备】应⽤数据分离架构 -- 分布系统的演进(2)

应⽤数据分离架构 随着系统的上线&#xff0c;我们不出意外地获得了成功。市场上出现了⼀批忠实于我们的⽤⼾&#xff0c;使得系统的访问量逐步上升&#xff0c;逐渐逼近了硬件资源的极限&#xff0c;同时团队也在此期间积累了对业务流程的⼀批经验。⾯对当前的性能压⼒&#x…

Android Studio学习8——点击事件

在xml代码中绑定 在java代码中绑定 弹出一个toast 随机&#xff0c;数组

基于Docker for Windows部署ChatGPT-Next-Web

基于Docker for Windows部署ChatGPT-Next-Web 项目地址安装Docker for Windows部署项目参数讲解参数示例 运行 项目地址 https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web 安装Docker for Windows 官网地址&#xff1a;https://www.docker.com/ 下拉找到Download 选择W…

篮球竞赛预约平台的设计与实现|Springboot+ Mysql+Java+ B/S结构(可运行源码+数据库+设计文档)篮球馆,篮球赛,竞赛项目,赛事预约

本项目包含可运行源码数据库LW&#xff0c;文末可获取本项目的所有资料。 推荐阅读300套最新项目持续更新中..... 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 2024年56套包含ja…

数据库系统概论(超详解!!!) 第三节 关系数据库标准语言SQL(Ⅳ)

1.集合查询 集合操作的种类 并操作UNION 交操作INTERSECT 差操作EXCEPT 参加集合操作的各查询结果的列数必须相同;对应项的数据类型也必须相同 查询计算机科学系的学生及年龄不大于19岁的学生。SELECT *FROM StudentWHERE Sdept CSUNIONSELECT *FROM StudentWHERE Sage&l…

go之web框架gin

介绍 Gin 是一个用 Go (Golang) 编写的 Web 框架。 它具有类似 martini 的 API&#xff0c;性能要好得多&#xff0c;多亏了 httprouter&#xff0c;速度提高了 40 倍。 如果您需要性能和良好的生产力&#xff0c;您一定会喜欢 Gin。 安装 go get -u github.com/gin-gonic/g…

SpringBoot | Spring Boot“整合Redis“

目录: 1. Redis 介绍2. Redis 下载安装3. Redis “服务开启”和“连接配置”4. Spring Boot整合Redis的“前期准备” :① 编写实体类② 编写Repository 接口③ 在“全局配置文件”中添加 “Redis数据库” 的 “相关配置信息” 5. Spring Boot整合“Redis” (案例展示) 作者简介…

Golang | Leetcode Golang题解之第5题最长回文子串

题目&#xff1a; 题解&#xff1a; func longestPalindrome(s string) string {if s "" {return ""}start, end : 0, 0for i : 0; i < len(s); i {left1, right1 : expandAroundCenter(s, i, i)left2, right2 : expandAroundCenter(s, i, i 1)if ri…

使用fusesource的mqtt-client-1.7-uber.jar,mqtt发布消息出去,接收端看到的是中文乱码,如何解决?

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…

安全架构设计理论与实践相关知识总结

一、安全架构概述 常见信息威胁介绍&#xff1a; 1. 信息泄露&#xff1a;信息被泄露或透露给某个非授权实体 2. 破坏信息完整性&#xff1a;数据被非授权地进行增删改查货破坏而受到损失 3. 拒绝服务&#xff1a;对信息会其他资源的合法访问被无条件的组织 4. 非法使用&#x…

Linux网络编程二(TCP图解三次握手及四次挥手、TCP滑动窗口、MSS、TCP状态转换、多进程/多线程服务器实现)

文章目录 1、TCP三次握手(1) 第一次握手(2) 第二次握手(3) 第三次握手 2、TCP四次挥手(1) 一次挥手(2) 二次挥手(3) 三次挥手(4) 四次挥手 3、TCP滑动窗口4、TCP状态时序图5、多进程并发服务器6、多线程并发服务器 1、TCP三次握手 TCP三次握手(TCP three-way handshake)是TCP协…

【单】Unity _RPG项目中的问题

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a; ⭐…

数字乡村创新之路:科技引领农村实现高质量发展

随着信息技术的快速发展&#xff0c;数字乡村建设已成为推动农村高质量发展的重要引擎。数字乡村通过科技创新&#xff0c;不仅改变了传统农业生产方式&#xff0c;也提升了乡村治理水平&#xff0c;为农民带来了更加便捷的生活。本文将从数字乡村的内涵、科技引领农村高质量发…

自贡市第一人民医院:超融合与 SKS 承载 HIS 等核心业务应用,加速国产化与云原生转型

自贡市第一人民医院始建于 1908 年&#xff0c;现已发展成为集医疗、科研、教学、预防、公共卫生应急处置为一体的三级甲等综合公立医院。医院建有“全国综合医院中医药工作示范单位”等 8 个国家级基地&#xff0c;建成高级卒中中心、胸痛中心等 6 个国家级中心。医院日门诊量…

57 npm run build 和 npm run serve 的差异

前言 npm run serve 和 npm run build 的差异 这里主要是从 vue-cli 的流程 来看一下 我们经常用到的这两个命令, 他到传递给 webpack 打包的时候, 的一个具体的差异, 大致是配置了那些东西? 经过了那些流程 ? vue-cli 的 vue-plugin 的加载 内置的 plugin 列表如下, 依次…

使用ffmpeg将视频解码为帧时,图像质量很差

当使用ffmpeg库自带的ffmpeg.exe对对视频进行解帧或合并时&#xff0c;结果质量很差。导致这种原因的是在使用ffmpeg.exe指令进行解帧或合并时使用的是默认的视频码率&#xff1a;200kb/s。 如解帧指令&#xff1a; ffmpeg.exe -i 600600pixels.avi -r 2 -f image2 img/%03d.…

Topaz Video AI for Mac v5.0.0激活版 视频画质增强软件

Topaz Video AI for Mac是一款功能强大的视频处理软件&#xff0c;专为Mac用户设计&#xff0c;旨在通过人工智能技术为视频编辑和增强提供卓越的功能。这款软件利用先进的算法和深度学习技术&#xff0c;能够自动识别和分析视频中的各个元素&#xff0c;并进行智能修复和增强&…

vue 加 websocket 聊天

<template><div style="height: 100%; width: 100%; background-color: #fff"><div class="wrap"><!-- 头部 --><div class="titleBox"><imgsrc="@/assets/image/avatar.png"style="argin: 10p…

windows部署Jenkins并远程部署tomcat

目录 1、Jenkins官网下载Jenkins 2、安装Jenkins 3、修改Home directory 4、插件安装及系统配置 5、Tomcat安装及配置 5.1、修改配置文件,屏蔽以下代码 5.2、新增登录用户 5.3、编码格式修改 5.4、启动tomcat 6、Jenkins远程部署war包 6.1、General配置 6.2、Sourc…