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

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

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

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】阈值化处理,红外目标块像素值为下表,可见还有较明显高斯噪声。

162

169

180

174

170

161

173

186

184

175

172

185

190

193

173

172

181

185

189

173

159

166

165

167

163

红外小目标检测中小目标的大小定义 红外弱小目标_红外

1.2、5×5高斯滤波

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

164

170

175

174

167

167

175

183

182

171

171

180

187

185

173

170

176

181

180

171

162

165

167

167

163

红外小目标检测中小目标的大小定义 红外弱小目标_opencv_02

2、效果展示



红外小目标检测中小目标的大小定义 红外弱小目标_人工智能_03

红外小目标检测中小目标的大小定义 红外弱小目标_红外_04


红外小目标检测中小目标的大小定义 红外弱小目标_人工智能_05

红外小目标检测中小目标的大小定义 红外弱小目标_计算机视觉_06


红外小目标检测中小目标的大小定义 红外弱小目标_红外_07

红外小目标检测中小目标的大小定义 红外弱小目标_人工智能_08


红外小目标检测中小目标的大小定义 红外弱小目标_opencv_09

红外小目标检测中小目标的大小定义 红外弱小目标_计算机视觉_10


红外小目标检测中小目标的大小定义 红外弱小目标_红外小目标检测中小目标的大小定义_11

红外小目标检测中小目标的大小定义 红外弱小目标_红外小目标检测中小目标的大小定义_12


红外小目标检测中小目标的大小定义 红外弱小目标_红外小目标检测中小目标的大小定义_13

红外小目标检测中小目标的大小定义 红外弱小目标_opencv_14


红外小目标检测中小目标的大小定义 红外弱小目标_计算机视觉_15

红外小目标检测中小目标的大小定义 红外弱小目标_opencv_16


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;
}

大功告成!