Conceptos básicos de OpenCV 4.1.1 (C ++)

Conceptos básicos de OpenCV4.1.1
Algún código de procesamiento de imágenes básico

1. Lectura de imágenes, visualización, denominación de ventanas, varios métodos para crear un nuevo objeto Mat y procesamiento de máscaras.

#include<opencv2/opencv.hpp>//OpenCV头文件
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
    
    
    Mat a = imread("C:/Users/Lenovo/Desktop/新建文件夹/ConsoleApplication2/智能窗户logo.png");//新建一个Mat对象
    namedWindow("输出1", WINDOW_AUTOSIZE);//命名一个叫"输出1"的窗口,第二个参数表示窗口大小调整但不能手动改变窗口大小
    imshow("输出1", a);//显示图像在窗口"输出1"

    Mat b;
    b.create(a.size(), a.type());//新建Mat对象新方法
    b = Scalar(0, 0, 0);//此时b为黑色
    namedWindow("输出2", WINDOW_NORMAL);//第二个参数表示可以手动改变窗口大小
    imshow("输出2", b);

    Mat c(300, 300, CV_8UC1, Scalar(127));//第三个参数决定了这是一个单通道灰度图像
    namedWindow("输出3", WINDOW_AUTOSIZE);
    imshow("输出3", c);

    Mat qq;
    Mat cc = (Mat_<float>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
    filter2D(a, qq, -1, cc);//掩膜处理
    namedWindow("output", WINDOW_AUTOSIZE);
    imshow("output", qq);

    Mat d;
    d.create(a.size(), a.type());
    bitwise_not(a, d);//函数作用是图像取反
    //imshow("output", d);

    waitKey(0);//加上这个窗口不会一闪而过,参数是显示的毫秒数,如果参数为0则窗口无限等待
               //该函数返回值为摁键的ASCII码数值,如果没有摁键返回-1
    return 0;
}
El tercer parámetro CV_8UC1 de la imagen c es una imagen predefinida, y la estructura predefinida es
CV_ <profundidad_bit> (S | U | F) C <número_de_canales>
① - bit_depth: número de bits: representa 8 bits, 16 bits, 32 bits, 64 bits, por ejemplo, por ejemplo,
Si ahora crea un objeto Mat que almacena una imagen en escala de grises, el tamaño de esta imagen es 100 de ancho y 100 de alto, entonces, ahora esto
Hay 10,000 píxeles en una imagen en escala de grises, y el espacio ocupado por cada píxel en el espacio de memoria es de 8 bits, 8 bits, por lo que corresponde a CV_8
② – S | U | F – S– son las siglas en inglés de —signed int —igned integer
U significa entero sin signo int sin signo
F - representa - flotante --------- punto flotante de precisión simple
③ - C <number_of_channels> ---- Representa el número de canales de una imagen, como:
1 — Imagen gris — grayImg — Sí — Imagen de un solo canal
2 – Imagen en color RGB --------- Sí – Imagen de 3 canales
3 - Imagen RGB con canal alfa - Sí - Imagen de 4 canales

2. Mezcla, suma y multiplicación proporcional de dos imágenes.

El principio de la mezcla de imágenes.

Inserte la descripción de la imagen aquí

#include<opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;

int main()
{
    
    
    Mat src1 = imread("C:/Users/Lenovo/Desktop/新建文件夹/ConsoleApplication3/智能窗户logo1.png");
    Mat src2 = imread("C:/Users/Lenovo/Desktop/新建文件夹/ConsoleApplication3/智能窗户logo2.png");
    if (!src1.data)//新的判断图像是否读取成功的方法
    {
    
    
        cout << "could not load 智能窗户logo1...";
        return -1;
    }
    if (!src2.data)
    {
    
    
        cout << "could not load 智能窗户logo2...";
        return -1;
    }
    int height = src1.rows;//得到高度
    int width = src1.cols;//得到宽度
    cout << height << "   " << width << endl;

    //两个图像按比例混合
    if (src1.rows == src2.rows && src1.cols == src2.cols)
    {
    
    
        Mat dst;//混合后的图像为dst
        double alpha = 0.4;
        //addWeighted(src1, alpha, src2, 1 - alpha, 0.0, dst);
        //add(src1, src2, dst, Mat());//这个函数只是单纯的像素相加
        multiply(src1, src2, dst, 1.0);//像素相乘
        namedWindow("智能窗户logo1", WINDOW_AUTOSIZE);
        namedWindow("智能窗户logo2", WINDOW_AUTOSIZE);
        namedWindow("混合logo", WINDOW_AUTOSIZE);

        imshow("智能窗户logo1", src1);
        imshow("智能窗户logo2", src2);
        imshow("混合logo", dst);
    }
    else
    {
    
    
        cout << "could not blend images,the size of images is not same...";
        return -1;
    }

    waitKey(0);
    return 0;
}

En tercer lugar, ajuste el brillo y el contraste de la imagen.

La transformación de imágenes se puede ver como:
Operación de punto de transformación de píxeles
Área de operación del vecindario
Ajuste el brillo y el contraste de la imagen a la operación puntual, el principio es el siguiente

Inserte la descripción de la imagen aquí

Cada píxel debe estar más cerca de 255, cuanto mayor sea el brillo
saturate_cast (valor) Asegúrese de que el valor esté en el rango de 0 ~ 255
Mat.at (y, x) (índice) = valor Asignar un valor a cada píxel y cada canal
Mat dst_k = Mat :: zeros (image.size (), image.type ()); Cree una nueva imagen en blanco con el mismo tamaño y tipo que la imagen original, e inicialice el valor de píxel a 0.
#include<opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;

int main()
{
    
    
    Mat src1 = imread("C:/Users/Lenovo/Desktop/新建文件夹/ConsoleApplication3/lly.jpg");
    if (!src1.data)
    {
    
    
        cout << "image could not load..." << endl;
        return -1;
    }
    string out_put_window = "output";
    int height = src1.rows;
    int width = src1.cols;
    float alpha = 1.2;
    int beta = 30;
    Mat dst_k = Mat::zeros(src1.size(), src1.type());//新建一个与原图像大小类型相同的空白图像、像素值初始化为0
    for (int row = 0; row < height; row++)
    {
    
    
        for (int col = 0; col < width; col++)
        {
    
    
            if (src1.channels() == 3)//如果是三通道图像
            {
    
    
                float b = src1.at<Vec3b>(row, col)(0);//blue
                float g = src1.at<Vec3b>(row, col)(1);//green
                float r = src1.at<Vec3b>(row, col)(2);//red

                //output
                dst_k.at<Vec3b>(row, col)(0) = saturate_cast<uchar>(alpha * b + beta);
                dst_k.at<Vec3b>(row, col)(1) = saturate_cast<uchar>(alpha * g + beta);
                dst_k.at<Vec3b>(row, col)(2) = saturate_cast<uchar>(alpha * r + beta);
            }
            else if (src1.channels() == 1)//如果是单通道图像
            {
    
    
                float v = src1.at<uchar>(row, col);
                dst_k.at<uchar>(row, col) = saturate_cast<uchar>(alpha * v + beta);
            }
        }
    }
    namedWindow("before", WINDOW_AUTOSIZE);
    imshow("before", src1);

    namedWindow(out_put_window, WINDOW_AUTOSIZE);
    imshow(out_put_window, dst_k);


    waitKey(0);
    return 0;
}

Cuarto, dibuja texto y gráficos.

Hay líneas rectas, círculos, elipses, rectángulos, polígonos, líneas rectas aleatorias, etc. en los gráficos.
API relacionada:
Genere un uniforme de números aleatorios de distribución normal (int a, int b)
Generar número aleatorio gaussiano gaussiano (sigma doble)
#include<opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
Mat src;
void myline();
void myRectangle();
void myEllipse();
void mycircle();
void myPolygon();
void Randomlinedemo();
int main()
{
    
    
    src = imread("C:/Users/Lenovo/Desktop/新建文件夹/ConsoleApplication3/lly.jpg");
    if (!src.data)
    {
    
    
        cout << "image could not load..." << endl;
        return -1;
    }
    string out_put_window = "output";
    myline();
    myRectangle();
    myEllipse();
    mycircle();
    myPolygon();
    putText(src, "HELLO WORLD!", Point(200, 100), FONT_HERSHEY_COMPLEX, 1.0, Scalar(12, 23, 255), 2, 8);
    //绘制文字函数原型,第一个参数是图像
    Randomlinedemo();

    namedWindow(out_put_window, WINDOW_AUTOSIZE);
    imshow(out_put_window, src);

    waitKey(0);
    return 0;
}
void myline()//线段
{
    
    
    Point p1 = Point(20, 30);
    Point p2;
    p2.x = 400;
    p2.y = 300;
    Scalar color = Scalar(0, 0, 225);
    line(src, p1, p2, color, 1, LINE_8);//绘制直线函数(图像,起始点,终止点,颜色,粗细,8连通)
}

void myRectangle()//正方形
{
    
    
    Rect rect_a = Rect(200, 100, 300, 300);
    Scalar color = Scalar(255, 0, 0);
    rectangle(src, rect_a, color, 1, LINE_8);
}
void myEllipse()//椭圆
{
    
    
    Scalar color = Scalar(0, 255, 0);
    ellipse(src, Point(src.rows / 2, src.cols / 2), Size(src.rows / 4, src.cols / 8), 90, 0, 360, color, 2, LINE_8);
    //椭圆(图像,原点,长半轴短半轴,旋转度数,从多少度开始,到多少度结束,颜色,粗细,8连通)
}
void mycircle()//园
{
    
    
    Scalar color = Scalar(0, 255, 255);
    circle(src,Point(500,500),200,color,3,LINE_8);
}
void myPolygon()//多边形
{
    
    
    Point pts[1][5];
    pts[0][0] = Point(100, 100);
    pts[0][1] = Point(100, 200);
    pts[0][2] = Point(200, 200);
    pts[0][3] = Point(200, 100);
    pts[0][4] = Point(100, 100);

    const Point* ppts[] = {
    
     pts[0] };
    int npt[] = {
    
     5 };
    Scalar color = Scalar(255, 255, 0);

    fillPoly(src, ppts, npt, 1, color, 8);//画填充
}
void Randomlinedemo()//随机线
{
    
    
    RNG rng(12345);
    Point p1;
    Point p2;
    Mat py = Mat::zeros(src.size(), src.type());//新建一个大小类型与src相同,一个黑色空白图像。
    namedWindow("py", WINDOW_AUTOSIZE);
    for (int i = 0; i < 100; i++)
    {
    
    
        p1.x = rng.uniform(0, src.rows);//生成正态分布随机数字
        p2.x = rng.uniform(0, src.rows);
        p1.y = rng.uniform(0, src.cols);
        p2.y = rng.uniform(0, src.cols);
        Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
        line(py, p1, p2, color, 1, 8);
        if (waitKey(50) > 0)
        {
    
    
            break;
        }
        imshow("py", py);
    }

}

Supongo que te gusta

Origin blog.csdn.net/Huo6666/article/details/107519423
Recomendado
Clasificación