OpenCV 4.1.1の基本(C ++)

OpenCV4.1.1の基本
いくつかの基本的な画像処理コード

1.画像の読み取り、表示、ウィンドウの命名、新しいMatオブジェクトを作成するいくつかの方法、およびマスク処理。

#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;
}
画像cの3番目のパラメータCV_8UC1は事前定義された画像であり、事前定義された構造は次のとおりです。
CV_ <bit_depth>(S | U | F)C <number_of_channels>
①--bit_depth-ビット数-は、たとえば、8ビット、16ビット、32ビット、64ビットを表します。
ここで、グレースケール画像を格納するMatオブジェクトを作成すると、この画像のサイズは幅100、高さ100になります。
グレースケール画像には10,000ピクセルがあり、メモリ空間の各ピクセルが占める空間は8ビット、8ビットであるため、CV_8に対応します。
②–S | U | F–S–は—signed int—signedintegerの略です
U-の略-unsignedint-unsigned integer
F--表す--float ---------単精度浮動小数点
③--C<number_of_channels> ----次のように、画像のチャネル数を表します。
1-グレー画像-grayImg-はい-シングルチャネル画像
2–RGBカラー画像---------はい–3チャンネル画像
3 –アルファチャンネル付きRGB画像–はい–4チャンネル画像

2. 2つの画像の比例混合、加算、乗算。

画像ミキシングの原理

ここに画像の説明を挿入

#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;
}

第三に、画像の明るさとコントラストを調整します

画像変換は次のように見ることができます:
ピクセル変換ポイント操作
近隣作戦エリア
画像の明るさとコントラストをポイント操作に調整します。原理は次のとおりです。

ここに画像の説明を挿入

各ピクセルは255に近くなければならず、明るさが高くなります
saturate_cast(value)値が0〜255の範囲内にあることを確認してください
Mat.at(y、x)(index)= value各ピクセルと各チャネルに値を割り当てます
Mat dst_k = Mat :: zeros(image.size()、image.type());元の画像と同じサイズとタイプの新しい空白の画像を作成し、ピクセル値を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;
}

第四に、テキストとグラフィックを描く

グラフィックには、直線、円、楕円、長方形、多角形、ランダムな直線などがあります。
関連API:
正規分布の乱数均一を生成します(int a、int b)
ガウス乱数を生成するgaussian(double sigma)
#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);
    }

}

おすすめ

転載: blog.csdn.net/Huo6666/article/details/107519423