根据自己在网课上的学习,记录一些笔记,加深记忆,在这里分享出来,大家一起学习,自己编程能力有限,对于一些专业名词的运用可能不太得当,不过希望能够让自己不断进步。如有不足不严谨之处希望大家指出来。
这次继续学一点简单的操作吧。
1.图像的混合
图像的混合即把两张大小一样类型一致的图像合成一张图片。
(1)理论知识
线性混合操作的理论:
g(x)=(1-⍺)f₀(x)+⍺f₁(x)
其中⍺代表了每个图像占的权重,⍺的取值范围为0~1之间。通过对⍺值的调整可以使得两张图片得到更好的融合。
(2)相关api
使用addWeighted(cv::InputArray src1, 输入图像1
double alpha, 输入图像1的alpha值
cv::InputArray src2, 输入图像2
double beta, 输入图像2的alpha值
double gamma, 这个是校验值,默认为0
double alpha=0.5;
if(src1.size()==src2.size()&&src1.type()==src2.type()){
addWeighted(src1,alpha, src2, (1.0-alpha), 0.0, dst);
imshow("qianxi", src1);
imshow("spiderman", src2);
namedWindow("blend image",CV_WINDOW_NORMAL);
imshow("blend image",dst);
}
else{
cout<<"this two pictures are not same size or type";
}
出来的效果图如下,中间那个图是两张图合成后的效果,嘻嘻嘻~大家有其他的创意也可以试着去实现:
把两个图合成一张图,也可以直接采用下面这种不基于权重方式,包括加法和乘法的合成,但是合成的效果非常生硬。一般不采取。代码如下:
add(src1,src2,dst,Mat());
multiply(src1,src2,dst);
2.调整图像亮度和对比度
(1)理论知识
图像变换有两种变换方式,一种是像素的变换——点操作,另一种是邻域操作下的变化——区域变换,后面这种图像变换可以用来做识别等比较复杂一些的图像计算。今天主要学会用第一种,像素变换(之前上一次我已经写了一些小的读取修改像素方面的知识,可以回顾一下)。
像素变换:
g(i,j)=⍺f(i,j)+β,其中⍺>0,β是增益变量。
对于这个式子的理解可以理解成这样。⍺是用来调整对比度的,β是用来调整亮度的,i、j是图像的像素点。
#include <iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
//提高图像的亮度和对比度
int main(int argc, const char * argv[]) {
Mat src,src2,dst;
src=imread("/Users/Meng/Documents/opencvTest/Pictures/WechatIMG1.jpeg");
if(!src.data){
cout<<"can not load image..."<<endl;
return -1;
}
//cvtColor(src, src2, CV_RGB2GRAY);//变成灰度图像
//src.convertTo(src2, CV_32F);//如果想使用vec3f需要提前转换一下
dst=Mat::zeros(src.size(),src.type());
int height=src.rows;
int width=src.cols;
float alpha=1.5;
float beta=10;
for(int row=0;row<height;row++){
for(int col=0;col<width;col++){//多通道rgb
if(src.channels()==3){
float b=src.at<Vec3b>(row,col)[0];
float g=src.at<Vec3b>(row,col)[1];
float r=src.at<Vec3b>(row,col)[2];
dst.at<Vec3b>(row,col)[0]=saturate_cast<uchar>(b*alpha+beta);
dst.at<Vec3b>(row,col)[1]=saturate_cast<uchar>(g*alpha+beta);
dst.at<Vec3b>(row,col)[2]=saturate_cast<uchar>(r*alpha+beta);
}//灰度图像
else if(src.channels()==1){
float gray=src.at<uchar>(row,col);
dst.at<uchar>(row,col)=saturate_cast<uchar>(gray*alpha+beta);
}
}
}
char input_title[]="spider man";
char output_title[]="contrast and brightness image";
namedWindow(input_title,CV_WINDOW_NORMAL);
imshow(input_title, src);
namedWindow(output_title,CV_WINDOW_NORMAL);
imshow(output_title, dst);
waitKey(0);
}
小插曲:在这里面有一段代码可以用来建一张新的空白图像,经常会用的到,可以掌握好这种方法。其实Mat对象有很多有意思的使用,大家可以自己查查,我也边学边用。代码如下:
dst=Mat::zeros(src.size(),src.type());
还有一处需要大家留意,谨记下段代码:
saturate_cast<uchar>(value);
这个很有用的,可以保证色彩值在0~255之间,如果不加这个图片可能会很奇怪很不自然的。
这段代码中包含灰度图像的测试,可以自己感兴趣去做一下~上面这段代码效果是这样的:
看了蜘蛛侠小哥哥,学习opencv很开心。继续努力哈哈哈~