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;
}
posted @ 2019-12-17 11:22  xyfun72  阅读(368)  评论(0编辑  收藏  举报