自学opencv日记,day6

形态学操作应用-提取水平与垂直线

原理方法
图像形态学操作时候,可以通过自定义的结构元素实现结构元素
对输入图像一些对象敏感、另外一些对象不敏感,这样就会让敏
感的对象改变而不敏感的对象保留输出。通过使用两个最基本的
形态学操作 – 膨胀腐蚀,使用不同的结构元素实现对输入图像
的操作、得到想要的结果。

  • 膨胀,输出的像素值是结构元素覆盖下输入图像的最大像素值
  • 腐蚀,输出的像素值是结构元素覆盖下输入图像的最小像素值

代码:


#include <opencv2/opencv.hpp>
#include <iostream>


	using namespace cv;
	int main(int argc, char** argv) {
		Mat src = imread("C:/Users/Administrator/Pictures/hello.png");
		if (src.empty()) {
			printf("不能加载图像");
			return -1;
		}
		namedWindow("创建成功", CV_WINDOW_AUTOSIZE);
		imshow("创建成功", src);
		Mat gray;
		cvtColor(src, gray, CV_BGR2GRAY);
		namedWindow("gray image", 1);
		imshow("gray image", gray);
		
		Mat binImg;
		adaptiveThreshold(~gray, binImg, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, -2);
		imshow("binary image", binImg);

		waitKey(0);
		return 0;
	}

在这里插入图片描述
图1-1 原图像灰度图像与二值图像

其中代码参数:
在这里插入图片描述

		Mat hline = getStructuringElement(MORPH_RECT, Size(src.cols / 16, 1), Point(-1, -1));//水平结构元素
		Mat vline = getStructuringElement(MORPH_RECT, Size(1, src.rows / 16), Point(-1, -1));//竖直结构元素
		Mat dst;
		Mat temp;
		erode(binImg, temp, hline);
		dilate(temp, dst, hline);
		bitwise_not(dst, dst);
		imshow("Final Result", dst);

开操作后提取水平线:
在这里插入图片描述
图1-2 提取水平线

开操作后提取竖直线:
在这里插入图片描述
图1-3 提取竖直线

开操作也可以用这一句:

morphologyEx(binImg, dst, CV_MOP_OPEN, vline);

bitwise_not(dst, dst);这一句是颜色反转。

应用:提取验证码
在这里插入图片描述
图1-4 效果图
注意:图片名称最好不要是中文。

图像金字塔

上采样和降采样
在这里插入图片描述

#include <opencv2/opencv.hpp>
#include <iostream>


using namespace cv;
int main(int argc, char** argv) {
	Mat src = imread("C:/Users/Administrator/Pictures/20160711084909.jpg");
	if (src.empty()) {
		printf("不能加载图像");
		return -1;
	}
	namedWindow("input image", CV_WINDOW_AUTOSIZE);
	imshow("input image", src);

	Mat dst, dstdown;
	pyrUp(src, dst, Size(src.cols * 2, src.rows * 2));
	imshow("output image", dst);
	pyrDown(src, dstdown, Size(src.cols / 2, src.rows / 2));
	imshow("output2 image", dstdown);
	waitKey(0);
	return 0;
}

在这里插入图片描述
图1-5 上采样和降采样

高斯不同(DOG)

Difference Of Gaussian

	Mat gray, g1, g2, dogImg;
	cvtColor(src, gray, CV_BGR2GRAY);
	GaussianBlur(gray, g1, Size(3, 3), 0, 0);
	GaussianBlur(g1, g2, Size(3, 3), 0, 0);
	subtract(g1, g2, dogImg, Mat());
	

	
	imshow("dogImg", dogImg);


	waitKey(0);
	return 0;
}

此时可以看到一点微弱的轮廓,是因为图像变化后不明显。
在这里插入图片描述
图1-6 不明显的高斯不同图

此时加入

	normalize(dogImg, dogImg, 255, 0, NORM_MINMAX);

将图像在0-255的地方归一化,如图所示:
在这里插入图片描述
图1-7 归一化后的高斯不同图

完整代码如下:

#include <opencv2/opencv.hpp>
#include <iostream>


using namespace cv;
int main(int argc, char** argv) {
	Mat src = imread("C:/Users/Administrator/Pictures/20160711084909.jpg");
	if (src.empty()) {
		printf("不能加载图像");
		return -1;
	}
	namedWindow("input image", CV_WINDOW_AUTOSIZE);
	imshow("input image", src);

	Mat dst, dstdown;
	
	//上采样
	pyrUp(src, dst, Size(src.cols * 2, src.rows * 2));
	imshow("output image", dst);
	
	//降采用
	pyrDown(src, dstdown, Size(src.cols / 2, src.rows / 2));
	imshow("output2 image", dstdown);

	//DOG
	Mat gray, g1, g2, dogImg;
	cvtColor(src, gray, CV_BGR2GRAY);
	GaussianBlur(gray, g1, Size(5, 5), 0, 0);
	GaussianBlur(g1, g2, Size(5, 5), 0, 0);
	subtract(g1, g2, dogImg, Mat());
	
	//归一化显示
	normalize(dogImg, dogImg, 255, 0, NORM_MINMAX);
	imshow("dogImg", dogImg);


	waitKey(0);
	return 0;
}

基本阈值操作

在这里插入图片描述

分割类型:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
超过阈值的就和阈值取相等。
在这里插入图片描述
小于阈值的取0.
在这里插入图片描述
大于阈值取0.

寻找阈值的方法:
在这里插入图片描述

  • 二值化阈值

代码:

#include <opencv2/opencv.hpp>
#include <iostream>


using namespace cv;
int threshold_value = 127;
int threshold_max = 255;
Mat src, dst;
const char* output_title = "binary image";
void Threshold_Demo(int, void*);
int main(int argc, char** argv) {
	src = imread("C:/Users/Administrator/Pictures/20160711084909.jpg");
	if (src.empty()) {
		printf("不能加载图像");
		return -1;
	}
	namedWindow("input image", CV_WINDOW_AUTOSIZE);
	namedWindow(output_title, CV_WINDOW_AUTOSIZE);
	imshow("input image", src);

	createTrackbar("Threshold Value", output_title, &threshold_value, threshold_max, Threshold_Demo);
	Threshold_Demo(0, 0);

	waitKey(0);
	return 0;
}


void Threshold_Demo(int, void*) {
	Mat gray;
	cvtColor(src, gray, CV_BGR2GRAY);
	threshold(gray, dst, threshold_value, threshold_max, THRESH_BINARY);//二值化阈值
	imshow(output_title, dst);

}

在这里插入图片描述
图1-8 二值化阈值

注意,如果需要生成动态调节结构元素的控制条,必须要先创建namedwindow这个窗口,如果直接imshow是不会生成控制条的。

  • 反向二值化阈值
threshold(gray, dst, threshold_value, threshold_max, THRESH_BINARY_INV);

在这里插入图片描述
图1-9 反向二值化阈值
这五种操作可以新建一个trackbar统一起来,用type_value来代表五种不同的操作。效果如下:
在这里插入图片描述
图1-10 五种操作集合
代码:

#include <opencv2/opencv.hpp>
#include <iostream>


using namespace cv;
int threshold_value = 127;
int threshold_max = 255;
int type_value = 2;
int type_max = 4;
Mat src, dst;
const char* output_title = "binary image";
void Threshold_Demo(int, void*);
int main(int argc, char** argv) {
	src = imread("C:/Users/Administrator/Pictures/20160711084909.jpg");
	if (src.empty()) {
		printf("不能加载图像");
		return -1;
	}
	namedWindow("input image", CV_WINDOW_AUTOSIZE);
	namedWindow(output_title, CV_WINDOW_AUTOSIZE);
	imshow("input image", src);

	createTrackbar("Threshold Value", output_title, &threshold_value, threshold_max, Threshold_Demo);
	createTrackbar("Type Value", output_title, &type_value, type_max, Threshold_Demo);//这个trackbar可以改变type_value的值
	Threshold_Demo(0, 0);



	waitKey(0);
	return 0;
}


void Threshold_Demo(int, void*) {
	Mat gray;
	cvtColor(src, gray, CV_BGR2GRAY);
	//threshold(gray, dst, threshold_value, threshold_max, THRESH_BINARY);//二值化阈值
	//threshold(gray, dst, threshold_value, threshold_max, THRESH_BINARY_INV);//反向二值化阈值
	threshold(gray, dst, threshold_value, threshold_max, type_value);
	imshow(output_title, dst);

}

threshold(gray, dst, 0, 255,THRESH_OTSU | type_value);//自动计算阈值
或者
threshold(gray, dst, 0, 255, THRESH_TRIANGLE | type_value);//自动计算阈值(直方)

这个操作可以自动计算阈值,将原代码中 threshold(gray, dst, threshold_value, threshold_max, type_value);替换即可。

PS:灰度图像才能进行阈值操作。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值