0


opencv入门

目录

窗口显示

图片的显示

#include<opencv2/opencv.hpp>#include<iostream>usingnamespace cv;usingnamespace std;intmain(){
    cv::Mat src =imread("C:/Users/26961/Desktop/dog.jpg");if(src.empty()){
        cout <<"图图片未加载"<< endl;return-1;}imshow("输入窗口", src);waitKey(0);//阻塞式等待destroyAllWindows();//销毁所有的窗口对象return0;}

并不能进行窗口的缩放,只是图片固定在创建的窗口上会固定尺寸

注意:

  • imread可以加载灰度图像
cv::Mat src =imread("C:/Users/26961/Desktop/dog.jpg", 
                                    IMREAD_GRAYSCALE);

显示效果:
在这里插入图片描述

namedWindow 可以进行窗口的缩放

#include<opencv2/opencv.hpp>#include<iostream>usingnamespace cv;usingnamespace std;intmain(){
    cv::Mat src =imread("C:/Users/26961/Desktop/dog.jpg");if(src.empty()){
        cout <<"图片未加载"<< endl;return-1;}//可以进行窗口的缩放namedWindow("输入窗口", WINDOW_FREERATIO);//WINDOW_FREERATIO -可以调整图片的自由比率imshow("输入窗口", src);waitKey(0);//阻塞式等待destroyAllWindows();return0;}

图片色彩的转换

1.色彩空间转换函数- cvtColor

COLOR_ BGR2GRAY =6彩色到灰度
COLOR_ _GRAY2BGR=8灰度到彩色
COLOR_ BGR2HSV =40 BGR到HSV
COLOR_ HSV2BGR =54 HSV到BGR

2.图像保存- imwrite

  • 第一个参数是图像保存路径
  • 第二个参数是图像内存对象

hsv和GRAY

  • H 、S 、V三个通道的取值范围在0~180之间, H、S可以改变图片的色彩,V可以改变图片的亮度。
voidQuickDemo::quick_space_demo(Mat& src){
    Mat gray, hsv;//用于存储灰色和彩色的Mat对象cvtColor(src, hsv, COLOR_BGR2HSV);//设置灰色cvtColor(src, gray, COLOR_BGR2GRAY);//设置彩色//调整图片的自由比率namedWindow("灰色", WINDOW_FREERATIO);namedWindow("hsv", WINDOW_FREERATIO);imshow("hsv", hsv);//显示转换后的图片imshow("灰色", gray);//显示转换后的图片//保存转换颜色后的图片imwrite("C:/Users/26961/Desktop/images/hsv.jpg", hsv);imwrite("C:/Users/26961/Desktop/images/gray.jpg", gray);}

main.cpp

#include<opencv2/opencv.hpp>#include<iostream>#include"quick_demo.h"usingnamespace cv;usingnamespace std;intmain(){
    cv::Mat src =imread("C:\\Users\\26961\\Desktop\\images\\dog.jpg");if(src.empty()){
        cout <<"图片未打开"<< endl;return-1;}//可以进行窗口的缩放,图片与窗口大小匹配namedWindow("输入窗口", WINDOW_FREERATIO);imshow("输入窗口", src);//彩色转换
    QuickDemo obj;
    obj.quick_space_demo(src);//将Mat 对象传递给quick_space_demo函数,将转换的图片保存到// C:/Users/26961/Desktop/images/路径中//阻塞等待waitKey(0);//销毁窗口对象destroyAllWindows();return0;}

在这里插入图片描述

openCV图像对象创建与赋值

图像对象的创建和赋值

voidQuickDemo::mat_creater_demo(Mat& src){
    Mat m1, m2;
    m1 = src.clone();//赋值方式一
    src.copyTo(m2);//赋值方式二cvtColor(src, m1, COLOR_BGR2HSV);//为了区别,将m1对象色彩设置为彩色imshow("m1对象", m1);imshow("m2对象", m2);}

创建 8 * 8 的空白对象

//设置8 * 8的空白图像,指定一个通道。
Mat m3 =Mat::zeros(Size(8,8), CV_8UC1);/*
    显示宽度、高度、通道。
*/
std::cout <<"width: "<< m3.cols <<" height: "<< m3.rows  
 <<" channels: "<< m3.channels()<< std::endl;//打印空白图像
std::cout << m3 << std::endl;

在这里插入图片描述

使用ones和zeros的区别
如果在创建空白Mat对象时,如果指定要创建3个通道的时候,但是此时是使用Mat::ones该方法进行创建的话都出现1和0交替的现象,并且1总是出现在1通道

Mat m3 =Mat::ones(Size(8,8), CV_8UC3);
std::cout <<"width: "<< m3.cols <<" height: "<< m3.rows  
 <<" channels: "<< m3.channels()<< std::endl;

在这里插入图片描述

而如果是使用Mat::zeros方法时,并不会发送该情况,而是全部会初始化为0。

Mat m3 =Mat::zeros(Size(8,8), CV_8UC3);

在这里插入图片描述

改变空白对象的色彩

Mat m3 =Mat::zeros(Size(500,500), CV_8UC3);
m3 =Scalar(255,0,0);//设置m3对象的色彩,这里会被设置为纯蓝色imshow("图像", m3);//显示m3对象            

Mat对象之间的深浅拷贝问题

void QuickDemo::mat_creater_demo(Mat& src){
    Mat m1, m2;
    m1 = src.clone();//赋值方式一
    src.copyTo(m2);//赋值方式二cvtColor(src, m1, COLOR_BGR2HSV);//为了区别,将m1对象色彩设置为彩色/*imshow("m1对象", m1);
    imshow("m2对象", m2);*/

    Mat m3 = Mat::zeros(Size(500,500), CV_8UC3);
    m3 =Scalar(255,0,0);//设置m3对象的色彩imshow("图像3", m3);
    std::cout <<"width: "<< m3.cols <<" height: "<< m3.rows  
     <<" channels: "<< m3.channels()<< std::endl;//浅拷贝
    Mat m4 = m3;
    m4 =Scalar(0,0,0);//修改了m3imshow("图像4", m4);//深拷贝
    Mat m5 = m3.clone();//深拷贝已经修改了的m3imshow("图像5", m5);}

如果只是单纯的进行浅拷贝的话,那么m4对象的改变会影响到m3对象, 直到m4被修改了后m3也会收到影响。

在这里插入图片描述

解决的方案就是让m4深拷贝m3,那么就不会导致m3发生改变

void QuickDemo::mat_creater_demo(Mat& src){
    Mat m3 = Mat::zeros(Size(500,500), CV_8UC3);
    m3 =Scalar(255,0,0);//设置m3对象的色彩imshow("图像3", m3);
    std::cout <<"width: "<< m3.cols <<" height: "<< m3.rows  
     <<" channels: "<< m3.channels()<< std::endl;//浅拷贝
    Mat m4 = m3.clone();
    m4 =Scalar(0,0,0);imshow("图像4", m4);//深拷贝
    Mat m5 = m3.clone();
    m5 =Scalar(160,20,20);imshow("图像5", m5);}

效果:

在这里插入图片描述

opencv图像像素点读写操作

  • 数组遍历
voidchangeimg(Mat &src){int w = src.cols;//列int h = src.rows;//行int dims = src.channels();//通道for(int i =0; i < h; i++){for(int j =0; j < w; j++){if(dims ==1){//单通道的灰度图像//获取[i, j]位置的像素值int pv = src.at<uchar>(i, j);//修改[i, j]位置的像素值
                src.at<uchar>(i, j)=255- pv;}//三个通道的像素点需要修改三次,因为三个通道的彩色图像每一个像素点可以存储3个值if(dims ==3){//3通道的彩色图像//Vec3b 是一个三通道的像素点,所以Vec3b对象包含三个值 
                Vec3b bgr = src.at<Vec3b>(i, j);
                src.at<Vec3b>(i, j)[0]=255- bgr[0];
                src.at<Vec3b>(i, j)[1]=255- bgr[1];
                src.at<Vec3b>(i, j)[2]=255- bgr[2];}}}}voidQuickDemo::pixel_vlist_demo(Mat& src){
    Mat m1 = src.clone();changeimg(m1);imshow("src图像", src);

    Mat m2 = src.clone();changeimg(m2);imshow("m2图像", m2);}

修改前 vs 修改后

在这里插入图片描述

  • 指针方式遍历
voidchangeimg2(Mat& src){int w = src.cols;//列int h = src.rows;//行int dims = src.channels();//通道for(int i =0; i < h; i++){// 获取行指针
        uchar* curr_row = src.ptr<uchar>(i);for(int j =0; j < w; j++){//获取列指针if(dims ==1){int pv =*curr_row;*curr_row++=255- pv;}if(dims ==3){//遍历一个像素点拥有三个值的图像*curr_row++=255-*curr_row;*curr_row++=255-*curr_row;*curr_row++=255-*curr_row;}}}}voidQuickDemo::pixel_vlist_demo(Mat& src){
    Mat m1 = src.clone();changeimg1(m1);imshow("src图像", m1);

    Mat m2 = src.clone();changeimg2(m2);imshow("m2图像", m2);}

图像像素的算术操作

除法操作两种方式

voidQuickDemo::operator_demo(Mat& src){
    Mat dst;
    dst = src /Scalar(2,2,2);imshow("算术操作", dst);}voidQuickDemo::operator_demo(Mat& src){
    Mat dst;
    Mat m =Mat::zeros(src.size(), src.type());
    m =Scalar(2,2,2);divide(src, m, dst);imshow("除法操作", dst);}

乘法操作

voidQuickDemo::operator_demo(Mat& src){
    Mat dst;
    Mat m =Mat::zeros(src.size(), src.type());
    m =Scalar(2,2,2);multiply(src, m, dst);//src 与 m相乘的结果放入dst中imshow("算术操作", dst);}

像素点相加

voidQuickDemo::operator_demo(Mat& src){//初始化dst, 用于存储m和src 运算后的结果值 
    Mat dst =Mat::zeros(src.size(), src.type());//初始化m对象
    Mat m =Mat::zeros(src.size(), src.type());
    m =Scalar(2,2,2);int h = src.rows;//获取行int w = src.cols;//获取列//计算 m对象和src的和值for(int i =0; i < h; i++){for(int j =0; j < w; j++){
            Vec3b p1 = src.at<Vec3b>(i, j);
            Vec3b p2 = m.at<Vec3b>(i, j);
            dst.at<Vec3b>(i, j)[0]=saturate_cast<uchar>(p1[0]+ p2[0]);
            dst.at<Vec3b>(i, j)[1]=saturate_cast<uchar>(p1[1]+ p2[1]);
            dst.at<Vec3b>(i, j)[2]=saturate_cast<uchar>(p1[2]+ p2[2]);}}imshow("算术操作", dst);}

算术运算常用的四个接口

//加法voidadd(src, m, dst);//减法voidsubtract(src, m, dst);//乘法voidmultiply(src, m, dst);//除法voiddivide(src, m, dst);

在这里插入图片描述


本文转载自: https://blog.csdn.net/m0_53421868/article/details/126638163
版权归原作者 爱生活,爱代码 所有, 如有侵权,请联系我们删除。

“opencv入门”的评论:

还没有评论