opencv_c++学习笔记day3
图像混合
#include<opencv2/opencv.hpp>
#include<math.h>
#include<iostream>
using namespace cv;
using namespace std;
int main(int agrc, char** agrv) {
Mat src1, src2, dst;
src1 = imread("test1.jpg");
src2 = imread("test2.jpg");
resize(src2, src2,src1.size());
addWeighted(src1, 0.5, src2, 0.5, 0.8, dst);
imshow("dst", dst);
waitKey(0);
return 0;
}
效果如下:
输出图像:
PS:在网上看到的一个可爱小姐姐的图,如有侵权立删。
图像模糊
均值滤波:易收到噪声的干扰,不能完全消除噪声,只能相对减弱噪声
中值滤波:对噪声不是那么敏感,能够较好的消除椒盐噪声,但是容易导致图像的不连续性
高斯滤波:对图像进行平滑的同时,同时能够更多的保留图像的总体灰度分布特征
双边滤波:边缘保护滤波方法,双边滤波就是最常用的边缘保护滤波方法(另一种常用来与双边滤波对比的边缘保护滤波方法——引导滤波)。双边滤波的思想很简单,在高斯滤波的基础上加入了像素值权重项,也就是说既要考虑距离因素,也要考虑像素值差异的影响,像素值越相近,权重越大。
medianBlur(src1, dst, 3);//中值滤波
Size kernal_size = cv::Size(5, 5);
GaussianBlur(src1, dst,kernal_size, 7);//高斯滤波
bilateralFilter(src1, dst, 15, 150, 3);//双边滤波 para1半径多少内的像素被滤波,para3差值为多少内像素被滤波
膨胀与腐蚀
膨胀:背景最大像素值替换锚点像素
dilate(src,dst,kernel)
腐蚀:背景最小像素值替换锚点像素
erode(src,dst,kernel)
相关API
getStructuringElement函数会返回指定形状和尺寸的结构元素。
shape( MORPH_RECT\MORPH_CROSS\MORPH_ELLPSE) 矩形、十字形、椭圆
size要为奇数
锚点 默认为Point(-1,-1),即中心像素
Mat getStructuringElement(int shape, Size esize, Point anchor = Point(-1, -1));
具体演示:
#include<opencv2/opencv.hpp>
#include<math.h>
#include<iostream>
using namespace cv;
using namespace std;
Mat src, dst;
char OUTPUT_WIN[] = "input_image";
//定义全局变量
int element_size = 3;//定义结构元素大小
int max_size = 21;
void CallBack_Demo(int, void*);
int main(int agrc, char** agrv) {
src= imread("test1.jpg");
namedWindow("input_image", WINDOW_AUTOSIZE);
imshow("input_image", src);
namedWindow(OUTPUT_WIN, WINDOW_AUTOSIZE);
createTrackbar("Element_Size", OUTPUT_WIN, &element_size, max_size, CallBack_Demo);//para3 是所需调整数值所在的地址 最后启动回调函数
//CallBack_Demo(0,0);
waitKey(0);
return 0;
}
void CallBack_Demo(int,void*) {
int s = element_size * 2 + 1;
Mat structuringElement = getStructuringElement(MORPH_CROSS, Size(s, s), Point(-1, -1));
dilate(src, dst, structuringElement, Point(-1, -1), 1);//膨胀
imshow(OUTPUT_WIN, dst);
return;
}
效果
膨胀:
腐蚀:
形态学操作
开操作(MORPH_OPEN)
先腐蚀后膨胀
可以去掉小的对象,假设对象是前景色,背景是黑色
闭操作(MORPH_Close)
先膨胀后腐蚀
可以填充小的洞,假设对象是前景色,背景是黑色
形态学梯度(MORPH_Close)
膨胀减去腐蚀
基本梯度(其他还包括-内部梯度,方向梯度)
效果如图:
erode(src, erode1, kernel, Point(-1, -1), 1);
dilate(src, dilate1, kernel, Point(-1, -1), 1);
dst = dilate1 - erode1;
顶帽(MORPH_TOPHAT)
顶帽是原图像与开操作之间的差值图像
黑帽(MORPH_BLACKHAT)
黑帽是闭操作与源图像的差值图像
提取水平线,垂直线
结构元素取水平线or垂直线即可
int main(int agrc, char** agrv) {
Mat src, src_gray, bin_img, dst,dst2,temp,temp2;
char OUTPUT_WIN[] = "output_image";
src= imread("test1.jpg");
cvtColor(src,src_gray, COLOR_BGR2GRAY);
adaptiveThreshold(src_gray,bin_img,255,ADAPTIVE_THRESH_MEAN_C,THRESH_BINARY,15,-2);//转换成二值图像
namedWindow("bin_img", WINDOW_AUTOSIZE);
imshow("bin_img", bin_img);
namedWindow(OUTPUT_WIN, WINDOW_AUTOSIZE);
Mat hline = getStructuringElement(MORPH_RECT, Size(src.cols/16,1), Point(-1, -1));//提取横线 注意这里的尺寸先输入wid后输入hei
Mat vline = getStructuringElement(MORPH_RECT, Size(1,src.rows/16), Point(-1, -1));//提取垂线
erode(bin_img, temp, hline);
dilate(temp, dst, hline);
erode(bin_img, temp2, vline);
dilate(temp2, dst2, vline);
//dst = dst + dst2;
//morphologyEx(bin_img,dst,MORPH_OPEN,kernel);
//erode(src, erode1, kernel, Point(-1, -1), 1);
//dilate(src, dilate1, kernel, Point(-1, -1), 1);
//dst = dilate1 - erode1;
imshow(OUTPUT_WIN, dst);
waitKey(0);
return 0;
}
效果如下:
去掉多余细节点线(好有用哇!)
用很小的kernel进行先腐蚀后膨胀,此时需要把要留住的主体作为像素质高的(白),背景为黑,前面先腐蚀掉小部分的白色,然后再膨胀回来。
int main(int agrc, char** agrv) {
Mat src, src_gray, bin_img, dst,temp;
char OUTPUT_WIN[] = "output_image";
src= imread("test2.jpg");
resize(src, src, Size(500, 300));
cvtColor(src,src_gray, COLOR_BGR2GRAY);
adaptiveThreshold(~src_gray,bin_img,255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY,15,-3);//转换成二值图像
namedWindow("bin_img", WINDOW_AUTOSIZE);
imshow("bin_img", ~bin_img);
namedWindow(OUTPUT_WIN, WINDOW_AUTOSIZE);
Mat kernel = getStructuringElement(MORPH_RECT, Size(3,3), Point(-1, -1));//用很小的kernal才能只去掉细节 保留大体
erode(bin_img, temp, kernel);
dilate( temp, dst, kernel);
imshow(OUTPUT_WIN, ~dst);
waitKey(0);
return 0;
}
我尊称为自动去污渍滚筒洗衣机!