【opencv】红外弱小目标标记

基于形态学的红外弱小目标提取是指利用形态学的方法从红外图像中识别和提取出那些 尺寸较小、强度较弱的目标或者特征。

形态学方法通常涉及形态学操作,如腐蚀、膨胀、开运算、闭运算等,这些操作可以对图像进行局部结构的操作和特征的增强,从而有助于弱小目标的凸显,从而帮助提取出目标。

本次实验用的是垃圾算法,主要操作就是像素阈值分割面积收缩

1、实验步骤

  1. 灰度载入源图像,判断图像是否正确载入;
  2. 观察图像是否有噪声,若图像有噪声对图像进行去噪处理。如图像0003.bmp和0005.bmp有高斯噪声,用5×5高斯卷积核去噪处理;
  3. 根据待提取红外弱小目标像素值设置进行两次阈值化处理,使待提取红外弱小目标与背景图像分割;
  4. 用合适结构元素对3)处理后图像进行 击中击不中操作;
  5. 对击中目标进行形态学膨胀操作;
  6. 绘制膨胀后图形外轮廓;
  7. 计算轮廓面积,根据面积筛选待提取红外弱小目标;
  8. 在源图中根据筛选目标位置绘制框选矩形。

1.1、3×3高斯滤波

0003图像,用3×3高斯核滤波,用【171,190】阈值化处理,红外目标块像素值为下表,可见还有较明显高斯噪声。

162169180174170
161173186184175
172185190193173
172181185189173
159166165167163

在这里插入图片描述

1.2、5×5高斯滤波

0003图像,用5×5高斯核滤波,用【170,188】阈值化处理,红外目标块像素值为下表,相较3×3高斯卷积核已有较大改善。

164170175174167
167175183182171
171180187185173
170176181180171
162165167167163

在这里插入图片描述

2、效果展示

3、代码

提供0001和0003代码,其它类似,自己调参。

3.1、0001代码

// 0001代码
void InfraredTarget0001()
{
	Mat src, dst;
	String Path = "C:/Users/39686/Desktop/红外弱小目标提取样例/0001.bmp";
	src = imread(Path);

	namedWindow("src0001", WINDOW_NORMAL);
	imshow("src0001", src);

	if (src.empty())
	{
		cout << "could not load image..." << endl;
		return;
	}

	Mat gray;
	cvtColor(src, gray, CV_BGR2GRAY);

	//二值化
	Mat binary;
	threshold(gray, binary, 200, 255, THRESH_BINARY_INV);
	namedWindow("binary0001", WINDOW_NORMAL);
	imshow("binary0001", binary);

	vector<vector<Point>>contours;
	vector<Vec4i>hierarchy;
	Mat mask = Mat::zeros(src.size(), CV_8UC3);

	//findContours输入为8位单通道图像
	findContours(binary, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);
	for (int i = 0; i < (contours.size()); i++)
	{
		double area = contourArea(contours[i]);
		if (area > 80.0)continue;
		Rect rect = boundingRect(contours[i]);

		//drawContours(dst, contours, i, Scalar(255), FILLED, 8, hierarchy);
		rectangle(src, rect, Scalar(0, 0, 255), 1, 8);
	}

	namedWindow("dst0001", WINDOW_NORMAL);
	imshow("dst0001", src);

	return;
}

3.2、0003代码

// 0003代码
void InfraredTarget0003()//
{
	Mat src, dst;
	String Path = "C:/Users/39686/Desktop/红外弱小目标提取样例/0003.bmp";
	src = imread(Path);

	namedWindow("src0003", WINDOW_NORMAL);
	imshow("src0003", src);

	if (src.empty())
	{
		cout << "could not load image..." << endl;
		return;
	}

	Mat gauss;
	GaussianBlur(src, gauss, Size(5, 5), 0, 0);

	Mat gray;
	cvtColor(gauss, gray, CV_BGR2GRAY);

	//二值化
	Mat binary, hitImg;

	threshold(gray, binary, 185, 255, 3);
	threshold(binary, binary, 191, 255, 4);
	
	namedWindow("binary0003", WINDOW_NORMAL);
	imshow("binary0003", binary);

	//膨胀
	Mat kern2 = getStructuringElement(MORPH_RECT, Size(25,25));
	morphologyEx(binary, hitImg, MORPH_CLOSE, kern2, Point(-1, -1), 1);
	namedWindow("dilate", WINDOW_NORMAL);

	imshow("dilate", hitImg);

	float kernal_data[5][5] =
	{
		{-1,-1,-1,-1,-1},
		{-1,-1,-1,-1,-1},
		{-1,-1,-1,-1,-1},
		{-1,-1,-1,-1,-1},
		{-1,-1,-1,-1,-1},
	};

	Mat kernel = Mat(5, 5, CV_32FC1, &kernal_data);

	//击中操作
	morphologyEx(binary, hitImg, MORPH_HITMISS, kernel);
	bitwise_not(hitImg, hitImg);
	namedWindow("hit0003", WINDOW_NORMAL);
	imshow("hit0003", hitImg);

	//膨胀
	vector<vector<Point>>contours;
	vector<Vec4i>hierarchy;
	Mat mask = Mat::zeros(src.size(), CV_8UC3);

	//findContours输入为8位单通道图像
	findContours(hitImg, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);
	for (int i = 0; i < (contours.size()); i++)
	{
		double area = contourArea(contours[i]);
		if (area > 20.0)continue;
		//if (area < 64.5)continue;
		Rect rect = boundingRect(contours[i]);

		drawContours(mask, contours, i, Scalar(255), FILLED, 8, hierarchy);
		rectangle(src, rect, Scalar(0, 0, 255), 1, 8);
	}

	namedWindow("dst0003", WINDOW_NORMAL);
	imshow("dst0003", src);
	
	return;
}

大功告成!

  • 15
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值