1. Image reading, display, window naming, several methods of creating a new Mat object, and mask processing.
#include<opencv2/opencv.hpp>//OpenCV头文件#include<iostream>usingnamespace cv;usingnamespace std;intmain(){
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码数值,如果没有摁键返回-1return0;}
The third parameter CV_8UC1 of image c is a predefined image, and the predefined structure is
CV_<bit_depth>(S|U|F)C<number_of_channels>
①--bit_depth—number of bits—represents 8bite,16bites,32bites,64bites—for example—for example,
If you now create a Mat object that stores a grayscale image, the size of this image is 100 wide and 100 high, then, now this
There are 10,000 pixels in a grayscale picture, and the space occupied by each pixel in the memory space is 8bite, 8 bits-so it corresponds to CV_8
②–S|U|F–S– stands for —signed int—signed integer
U-stands for-unsigned int-unsigned integer
F--represents--float---------single precision floating point
③--C<number_of_channels>----Represents the number of channels of a picture, such as:
2. Proportional mixing, addition and multiplication of two images.
The principle of image mixing
#include<opencv2/opencv.hpp>#include<iostream>usingnamespace cv;usingnamespace std;intmain(){
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;//混合后的图像为dstdouble 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);return0;}
Third, adjust the image brightness and contrast
Image transformation can be seen as:
Pixel transformation-point operation
Neighborhood operation-area
Adjust the image brightness and contrast to point operation, the principle is as follows
Each pixel must be closer to 255, the higher the brightness
saturate_cast(value) Ensure that the value is in the range of 0~255
Mat.at(y,x)(index) =value Assign a value to each pixel and each channel
Mat dst_k = Mat::zeros(image.size(), image.type()); Create a new blank image with the same size and type as the original image, and initialize the pixel value to 0.
#include<opencv2/opencv.hpp>#include<iostream>usingnamespace cv;usingnamespace std;intmain(){
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());//新建一个与原图像大小类型相同的空白图像、像素值初始化为0for(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);//bluefloat g = src1.at<Vec3b>(row, col)(1);//greenfloat 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);}elseif(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);return0;}
Fourth, draw text and graphics
There are straight lines, circles, ellipses, rectangles, polygons, random straight lines, etc. in the graphics.
Related API:
Generate a normal distribution random number uniform(int a, int b)
Generate Gaussian random number gaussian(double sigma)
#include<opencv2/opencv.hpp>#include<iostream>usingnamespace cv;usingnamespace std;
Mat src;voidmyline();voidmyRectangle();voidmyEllipse();voidmycircle();voidmyPolygon();voidRandomlinedemo();intmain(){
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);return0;}voidmyline()//线段{
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连通)}voidmyRectangle()//正方形{
Rect rect_a =Rect(200,100,300,300);
Scalar color =Scalar(255,0,0);rectangle(src, rect_a, color,1, LINE_8);}voidmyEllipse()//椭圆{
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连通)}voidmycircle()//园{
Scalar color =Scalar(0,255,255);circle(src,Point(500,500),200,color,3,LINE_8);}voidmyPolygon()//多边形{
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);//画填充}voidRandomlinedemo()//随机线{
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);}}