OpenCV学习 day4 绘制形状与文字 图像模糊
1. 绘制形状与文字
绘制线段:line()
void MyLines() { Point p1(20, 30); Point p2; p2.x = 300; p2.y = 300; Scalar color = Scalar(0, 0, 255); line(bgImage, p1, p2, color, 2, LINE_AA); //LINA_AA 不要锯齿 }
绘制矩形:rectangle()
void MyRectangle() { Rect rect = Rect(20, 30, 280, 270); //x y w h Scalar color = Scalar(0, 255, 0); rectangle(bgImage, rect, color, 3, LINE_AA); }
绘制椭圆:ellipse()
void MyEllipse() { //Size axes1(bgImage.cols / 4, bgImage.rows / 8); //横轴 竖轴 //Size axes2; //axes2.width = bgImage.cols / 4; //axes2.height = bgImage.rows / 8; ellipse(bgImage, Point(bgImage.cols / 2, bgImage.rows / 2), Size(bgImage.cols / 4, bgImage.rows / 8), 60, 0, 360, Scalar(255, 0, 0), 2, LINE_8); //形状顺时针旋转60度 顺时针绘制360度 }
绘制圆:circle()
void MyCircle() { Point center(bgImage.cols / 2, bgImage.rows / 2); circle(bgImage, center, bgImage.cols / 4, Scalar(0, 255, 255), 2, 8); }
绘制填充的多边形:fillPoly()
void MyPolygon() { Point pts[1][6]; pts[0][0] = Point(100, 100); pts[0][1] = Point(400, 70); pts[0][2] = Point(500, 150); pts[0][3] = Point(300, 200); pts[0][4] = Point(150, 150); pts[0][5] = Point(100, 100); const Point* ppts[] = { pts[0] }; int npt[] = { 6 }; fillPoly(bgImage, ppts, npt, 1, Scalar(255, 255, 0), 8); }
绘制文字:putText()
void MyText() { char text[] = "Hello, OpenCV"; putText(bgImage, text, Point(300, 300), FONT_HERSHEY_COMPLEX, 1, Scalar(255, 0, 255), 2, 8); }
demo:
#include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace std; Mat bgImage; const char* drawdemo_win = "draw shapes and text demo"; void MyLines(); void MyRectangle(); void MyEllipse(); void MyCircle(); void MyPolygon(); void MyText(); int main() { bgImage = imread("D:/learning/image/3.jpg", IMREAD_UNCHANGED); if (bgImage.empty()) { cout << "Could not find the image!" << endl; return -1; } MyLines(); MyRectangle(); MyEllipse(); MyCircle(); MyPolygon(); MyText(); namedWindow(drawdemo_win, WINDOW_AUTOSIZE); imshow(drawdemo_win, bgImage); waitKey(0); return 0; }
随机生成多条不同颜色的线段:
void RandomLines() { RNG rng(12345); //随机种子 Point p1, p2; Mat bg = Mat::zeros(bgImage.size(), bgImage.type()); //生成黑色背景图 namedWindow("random lines demo", WINDOW_AUTOSIZE); //循环显示 for (int i = 0; i < 100000; i++) { p1.x = rng.uniform(0, bgImage.cols); //产生均匀分布的随机数 p2.x = rng.uniform(0, bgImage.rows); p1.y = rng.uniform(0, bgImage.cols); p2.y = rng.uniform(0, bgImage.rows); Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)); line(bg, p1, p2, color, 2, 8); imshow("random lines demo", bg); if (waitKey(50) > 0) break; } }
2.图像模糊
图像滤波的目的有两个:一是抽出对象的特征作为图像识别的特征模式;另一个是为适应图像处理的要求,消除图像数字化时所混入的噪声。
而对滤波处理的要求也有两条:一是不能损坏图像的轮廓及边缘等重要信息;二是使图像清晰视觉效果好。
也就是卷积的过程
均值滤波:
void blur( InputArray src, OutputArray dst, Size ksize, Point anchor = Point(-1,-1), int borderType = BORDER_DEFAULT );
Point默认(-1,-1),表示锚点在卷积核的正中心
Size中的数是奇数,Size(15,1)表示x方向的模糊,Size(1,15)表示y方向的模糊,数字越大,模糊程度越大。
高斯滤波:
void GaussianBlur( InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY = 0, int borderType = BORDER_DEFAULT );
sigmaX和sigmaY控制高斯核的陡峭 这两个值越大,图像越平滑,模糊效果越明显
https://blog.csdn.net/syp1992223/article/details/80233842
https://blog.csdn.net/lz0499/article/details/54015150/
中值滤波:
void medianBlur( InputArray src, OutputArray dst, int ksize );
ksize
关于均值滤波和中值滤波,可以看这个博客https://blog.csdn.net/qinghuaci666/article/details/81737624
中值滤波可以很好的消除椒盐噪声
双边滤波:
void bilateralFilter( InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace, int borderType = BORDER_DEFAULT );
d-计算的半径,如果为-1则根据sigmaSpace计算
sigmaColor-多少差值之内的像素会被计算,值越大模糊的越厉害
sigmaSpace-如果d大于0则声明无效,否则根据它来计算d值
均值滤波无法克服边缘像素信息丢失缺陷,原因是均值滤波是基于平均权重
高斯模糊部分克服了该缺陷,但无法完全避免,因为只是基于空间位置上的权重不同,没有考虑图像上像素值的不同
高斯双边模糊是边缘保留的滤波方法,避免了边缘信息丟失,保留了图像轮廓不变,
适合做美颜
int main(int argc, char** argv) { Mat src, b_dst, gb_dst, mb_dst, bt_dst; src = imread("D:/learning/image/8.jpg", WINDOW_AUTOSIZE); if (src.empty()) { cout << "can not found image..." << endl; return -1; } char input_win[] = "input image"; namedWindow(input_win, WINDOW_AUTOSIZE); imshow(input_win, src); //均值滤波 blur(src, b_dst, Size(11, 11), Point(-1, -1)); imshow("blur image", b_dst); //高斯滤波 GaussianBlur(src, gb_dst, Size(11, 11), 11, 11); imshow("gaussian blur image", gb_dst); //中值滤波 medianBlur(src, mb_dst, 3); imshow("median blur image", mb_dst); //双边高斯滤波 bilateralFilter(src, bt_dst, 5, 100, 3); imshow("biblur image", bt_dst); //对双边模糊再做处理 Mat kernel = (Mat_<int>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0); //定义滤波器 Mat final_im; filter2D(bt_dst, final_im, -1, kernel, Point(-1, -1)); imshow("final image", final_im); waitKey(0); return 0; }