OpenCV3学习笔记精炼(一)---- 图像读取显示等基本操作


1、读取图像

Mat imread(const string& filename, intflags=1 );

  • filename:图片路径;
  • intflags:通道数 默认值为1(三通道彩色图),可选值0(灰度图),CVLOADIMAGEANYDEPTH |  CVLOADIMAGEANYCOLOR(可读取16位或者32位,不选该属性则只能读取八位图像)

2、显示图像

(1)创建窗口

void namedWindow(const string& winname,int flags=WINDOW_AUTOSIZE );

  • winname:窗口名称;
  • flags:默认值:WINDOWAUTOSIZE(窗口大小会自动调整以适应所显示的图像)、可选值WINDOWNORMAL(用户便可以改变窗口的大小)、WINDOW_OPENGL(窗口创建的时候便会支持OpenGL)。

(2)显示图像

void imshow(const string& winname, InputArray mat);

  • winname:窗口名称;
  • mat:要显示的图像

(3)图片显示时间

waitKey()

这个函数是在一个给定的时间内(单位ms)等待用户按键触发;如果用户没有按下 键,则接续等待(循环),若值为0,则一直等待用户任意按键触发

3、写入文件

bool imwrite(const string& filename,InputArray img, const vector<int>& params=vector<int>() );

  • filename:保存后的文件名称。
  • img:要保存的图片
  • params:自己百度吧

4、图像融合

(1)利用ROI将一幅图加到另一幅图的指定位置
设定感兴趣区域——ROI(region of interest) 输出图像是原图上左上角坐标为(250,200),长宽为logo图长宽的那一小块,大小为logo图大小

void ROI_AddImage() {  
   //【1】读入图像  
   Mat srcImage1= imread("dota_pa.jpg");  
   Mat logoImage= imread("dota_logo.jpg"); 
   
   //【2】定义一个Mat类型并给其设定ROI区域  
   Mat imageROI= srcImage1(Rect(200,250,logoImage.cols,logoImage.rows));
   // Mat imageROI= srcImage1(Range(200,200+logoImage.rows),Range(250,250+logoImage.cols));
  
   //【3】加载掩模(必须是灰度图)直接将插入处的像素设置为logo图像的像素值  
   Mat mask= imread("dota_logo.jpg",0);  
   
   //【4】将掩膜拷贝到ROI   A = copyTo(B,MASK)。B是A一个附加掩膜MASK之后的图像矩阵
   logoImage.copyTo(imageROI,mask);  
   
   //【5】显示结果  
   namedWindow("<1>利用ROI实现图像叠加示例窗口");  
   imshow("<1>利用ROI实现图像叠加示例窗口",srcImage1);  
   
}

其中openCV中image.copyTo()有两种形式:

  • image.copyTo(imageROI),作用是把image的内容粘贴到imageROI;

  • image.copyTo(imageROI,mask),作用是把mask和image重叠以后把mask中像素值为0(black)的点对应的image中的点变为透明,而保留其他点。就比如ps中给图层加上一层蒙版,黑色的蒙版区域是不要的,非黑色的区域是要的

在本例中,如果logo是一个黑底白字的,加上与原图一样的蒙版后,logo就只剩下文字,背景编程透明了 tupian

(2)用addWeight函数:计算两个图像的加权和 

void addWeighted(InputArray src1, double alpha, InputArray src2, double beta, double gamma, OutputArray dst, int dtype=-1);
  • 第一个参数,InputArray类型的src1,表示需要加权的第一个数组,常常填一个Mat。
  • 第二个参数,alpha,表示第一个数组的权重
  • 第三个参数,src2,表示第二个数组,它需要和第一个数组拥有相同的尺寸和通道数。
  • 第四个参数,beta,表示第二个数组的权重值。
  • 第五个参数,gamma,一个加到权重总和上的标量值。
  • 第六个参数,dst,输出的数组,它和输入的两个数组拥有相同的尺寸和通道数。
    dst = src1[I] * alpha+ src2[I] * beta + gamma;
  • 第七个参数,dtype,输出阵列的可选深度,有默认值-1。;当两个输入数组具有相同的深度时,这个参数设置为-1(默认值),即等同于src1.depth()。
void LinearBlending()  
{  
           //【0】定义一些局部变量  
       double alphaValue = 0.5;  
       double betaValue;  
       Mat srcImage2, srcImage3, dstImage;  
   
       //【1】读取图像 ( 两幅图片需为同样的类型和尺寸 )  
       srcImage2= imread("mogu.jpg");  
       srcImage3= imread("rain.jpg");  
   
       //【2】做图像混合加权操作  
       betaValue= ( 1.0 - alphaValue );  
       //参数相当于两张图片的透明度,然后叠加
       addWeighted(srcImage2, alphaValue, srcImage3, betaValue, 0.0, dstImage);  
   
       //【3】创建并显示原图窗口  
       namedWindow("<2>线性混合示例窗口【原图】", 1);  
       imshow("<2>线性混合示例窗口【原图】", srcImage2 );  
   
       namedWindow("<3>线性混合示例窗口【效果图】", 1);  
       imshow("<3>线性混合示例窗口【效果图】", dstImage );  
     
        
}  

方法一和方法二的结合:

//---------------------------------【ROI_LinearBlending()】-------------------------------------  
// 函数名:ROI_LinearBlending()  
// 描述:线性混合实现函数,指定区域线性图像混合.利用cv::addWeighted()函数结合定义  
//                     感兴趣区域ROI,实现自定义区域的线性混合  
//--------------------------------------------------------------------------------------------  
bool ROI_LinearBlending()  
{  
   
       //【1】读取图像  
       Mat srcImage4= imread("dota_pa.jpg",1);  
       Mat logoImage= imread("dota_logo.jpg");  
   
       if(!srcImage4.data ) { printf("读取srcImage4错误~! \n"); return false; }  
       if(!logoImage.data ) { printf("读取logoImage错误~! \n"); return false; }  
   
       //【2】定义一个Mat类型并给其设定ROI区域  
       Mat imageROI;  
              //方法一  
       imageROI=srcImage4(Rect(200,250,logoImage.cols,logoImage.rows));  
       //方法二  
       //imageROI=srcImage4(Range(250,250+logoImage.rows),Range(200,200+logoImage.cols));  
   
       //【3】将logo加到原图上  
       addWeighted(imageROI,0.5,logoImage,0.3,0.,imageROI);  
   
       //【4】显示结果  
       namedWindow("<4>区域线性图像混合示例窗口 ");  
       imshow("<4>区域线性图像混合示例窗口 ",srcImage4);  
        
       return true;  
}  

5、分离通道&多通道融合

(1)spite 将一个多通道数组变成多个单通道数组 

void cv::split(  
    const cv::Mat& mtx, //输入图像  
    vector<Mat>& mv // 输出的多通道序列(n个单通道序列)  
); 

(2)merge 与spite相反,将多个数组合并成一个多通道的数组 

void merge(  
    const vector<cv::Mat>& mv, // 输入的多通道序列(n个单通道序列)  
    cv::OutputArray dst // 输出图像,包含mv  
); 

示例代码:

void spite&merge() {

    Mat src = imread("lenna.jpg", IMREAD_COLOR);  
    imshow("src", src);  
  
    // 将图片分解成多个通道 
    vector<Mat> rgbChannels(3);  
    split(src, rgbChannels);  
  
    // 显示单个通道
    Mat blank_ch, fin_img;  
    blank_ch = Mat::zeros(cv::Size(src.cols, src.rows), CV_8UC1);  
  
    // 以红色通道为例
    // 为了直观显示,将G和B置为零矩阵
    vector<Mat> channels_r;  
    channels_r.push_back(blank_ch);  
    channels_r.push_back(blank_ch);  
    channels_r.push_back(rgbChannels[2]);  
  
    /// Merge the three channels  
    merge(channels_r, fin_img);  
    imshow("R", fin_img);  
}

猜你喜欢

转载自blog.csdn.net/zyhhhh233/article/details/80282131
今日推荐