在进行图像处理时,为了更加直观的观察处理效果,经常需要在图中画出一些形状。此教程主要介绍OpenCV常见的绘画功能:
目录
函数声明:
//! draws the line segment (pt1, pt2) in the image
CV_EXPORTS_W void line(CV_IN_OUT Mat& img, Point pt1, Point pt2, const Scalar& color,
int thickness=1, int lineType=8, int shift=0);
函数说明:
函数使用注意事项:
(1)const Scalar& color的顺序是B、G、R
//创建一幅空白图像
cv::Mat src = cv::Mat::zeros(200, 200, CV_8UC3);
//画直线
cv::line(src, cv::Point(20, 20), cv::Point(40, 20), cv::Scalar(255, 0, 0), 1, 8, 0);
cv::line(src, cv::Point(20, 25), cv::Point(40, 25), cv::Scalar(0, 255, 0), 1, 8, 0);
cv::line(src, cv::Point(20, 30), cv::Point(40, 30), cv::Scalar(0, 0, 255), 1, 8, 0);
(2)int thickness 线宽的含义
//创建一幅空白图像
cv::Mat src = cv::Mat::zeros(200, 200, CV_8UC3);
//画直线
cv::line(src, cv::Point(20, 20), cv::Point(30, 20), cv::Scalar(255, 0, 0), 3, 8, 0);
可以看到当线宽thickness 设置为3时,线的总宽度L并不是为3,而是为L = 2 * thickness - 1
函数声明:
//! draws the rectangle outline or a solid rectangle with the opposite corners pt1 and pt2 in the image
CV_EXPORTS_W void rectangle(CV_IN_OUT Mat& img, Point pt1, Point pt2,
const Scalar& color, int thickness=1,
int lineType=8, int shift=0);
//! draws the rectangle outline or a solid rectangle covering rec in the image
CV_EXPORTS void rectangle(CV_IN_OUT Mat& img, Rect rec,
const Scalar& color, int thickness=1,
int lineType=8, int shift=0);
函数说明:
函数使用:
//创建一幅空白图像
cv::Mat src = cv::Mat::zeros(200, 200, CV_8UC3);
//画矩形
cv::rectangle(src, cv::Point(20, 20), cv::Point(35, 35), cv::Scalar(0, 0, 255), 1, 8, 0);
画矩形时线宽的含义与画直线线宽的含义是相同的。
//画矩形
cv::rectangle(src, cv::Point(20, 20), cv::Point(35, 35), cv::Scalar(0, 0, 255), 2, 8, 0);
使用Rect rec时,与Point pt1, Point pt2时的对应关系:
rec.x = min(P1.x, P2.x)
rec.y = min(P1.y, P2.y)
rec.width = max(P1.x, P2.x) - min(P1.x, P2.x) + 1
rec.height = max(P1.y, P2.y) - min(P1.y, P2.y) + 1
注意计算高度宽度时需要加1.
//画矩形
//cv::rectangle(src, cv::Point(20, 20), cv::Point(35, 35), cv::Scalar(0, 0, 255), 1, 8, 0);
//画矩形
cv::rectangle(src, cv::Rect(20, 20, 16, 16), cv::Scalar(0, 0, 255), 1, 8, 0);
可以看出画矩形函数只能画出那种对称轴与坐标轴平行的矩形,不能画出那种斜着的矩形。如果想要画出斜着的矩形,只能用line画出四条线来表示矩形了。
函数声明:
//! draws the circle outline or a solid circle in the image
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);
函数说明:
函数使用:
//创建一幅空白图像
cv::Mat src = cv::Mat::zeros(200, 200, CV_8UC3);
//画圆
cv::circle(src, cv::Point(80, 80), 10, cv::Scalar(255, 0, 0), 1, 8, 0);
函数声明:
//! draws an elliptic arc, ellipse sector or a rotated ellipse in the image
CV_EXPORTS_W void ellipse(CV_IN_OUT Mat& img, Point center, Size axes,
double angle, double startAngle, double endAngle,
const Scalar& color, int thickness=1,
int lineType=8, int shift=0);
//! draws a rotated ellipse in the image
CV_EXPORTS_W void ellipse(CV_IN_OUT Mat& img, const RotatedRect& box, const Scalar& color,
int thickness=1, int lineType=8);
函数说明:
画椭圆中三个角度的含义分别是什么?这个含义从内部原理分析肯定能准确的知道,但是目前我还看不懂椭圆绘制的源码。所以尝试用程序结合绘制的结果来分析。
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
//创建一幅空白图像
cv::Mat src = cv::Mat::zeros(1000, 1000, CV_8UC3);
//画椭圆1
cv::ellipse(src, cv::Point(200, 200), cv::Size(100, 80), 0, 0, 360, cv::Scalar(0, 255, 0), 1, 8, 0);
//标出椭圆1中心
cv::circle(src, cv::Point(200, 200), 1, cv::Scalar(0, 0, 255), 1, 8, 0);
//画椭圆2
cv::ellipse(src, cv::Point(200, 450), cv::Size(100, 80), 30, 0, 360, cv::Scalar(0, 255, 0), 1, 8, 0);
//标出椭圆2中心
cv::circle(src, cv::Point(200, 450), 1, cv::Scalar(0, 0, 255), 1, 8, 0);
//画椭圆3
cv::ellipse(src, cv::Point(450, 200), cv::Size(100, 80), 0, 30, 360, cv::Scalar(0, 255, 0), 1, 8, 0);
//标出椭圆3中心
cv::circle(src, cv::Point(450, 200), 1, cv::Scalar(0, 0, 255), 1, 8, 0);
//画椭圆4
cv::ellipse(src, cv::Point(450, 450), cv::Size(100, 80), 0, 0, 330, cv::Scalar(0, 255, 0), 1, 8, 0);
//标出椭圆4中心
cv::circle(src, cv::Point(450, 450), 1, cv::Scalar(0, 0, 255), 1, 8, 0);
//画椭圆5
cv::ellipse(src, cv::Point(450, 650), cv::Size(100, 80), 0, 330, 0, cv::Scalar(0, 255, 0), 1, 8, 0);
//标出椭圆5中心
cv::circle(src, cv::Point(450, 650), 1, cv::Scalar(0, 0, 255), 1, 8, 0);
//画椭圆6
cv::ellipse(src, cv::Point(750, 650), cv::Size(100, 80), 0, 330, 390, cv::Scalar(0, 255, 0), 1, 8, 0);
//标出椭圆6中心
cv::circle(src, cv::Point(750, 650), 1, cv::Scalar(0, 0, 255), 1, 8, 0);
//画椭圆7
cv::ellipse(src, cv::Point(750, 850), cv::Size(100, 80), 0, 390, 330, cv::Scalar(0, 255, 0), 1, 8, 0);
//标出椭圆7中心
cv::circle(src, cv::Point(750, 850), 1, cv::Scalar(0, 0, 255), 1, 8, 0);
return 0;
}
思考一下:如果startAngle == endAngle,画出的效果是怎样的???