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就只剩下文字,背景编程透明了
(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);
}