低小慢目标光电探测技术研究论文仿真

在这里插入图片描述
在这里插入图片描述
imageEnhance.h

#pragma once
#include<opencv2/opencv.hpp>
#include<iostream>
#include<vector>

#define radio 1.0
#define k 15// 将奇异值矩阵 V 内的所有元素 Vi按从小到大的顺序排列

class imageEnhanceSVD
{
public:
	imageEnhanceSVD();
	~imageEnhanceSVD();
	cv::Mat preProcessSVD(cv::Mat src);
private:
	cv::Mat outImage;
};

imageEnhance.cpp

#include"imageEnhance.h"

imageEnhanceSVD::imageEnhanceSVD()
{

}
imageEnhanceSVD::~imageEnhanceSVD()
{

}

cv::Mat imageEnhanceSVD::preProcessSVD(cv::Mat src)
{
	src.convertTo(src, CV_64FC1);
	cv::Mat U, W, V;
	cv::SVD::compute(src, W, U, V);
	cv::sort(W, W, cv::SORT_EVERY_ROW + cv::SORT_ASCENDING);//升序,从小到大
	for (int i = 0; i < W.rows; i++)
	{

		W.ptr<double>(i)[0] = k*(cv::sqrt(W.ptr<double>(i)[0]));
		
	}
	

	int set_dim = cv::min(src.rows, src.cols);
	int set_rows = set_dim*radio;

	cv::Mat W_ = cv::Mat(set_dim, set_dim, CV_64FC1, cv::Scalar(0));
	for (int i = 0; i < set_rows; i++)
	{
		W_.at<double>(i, i) = W.at<double>(i, 0); //opencv进行SVD分解后得到的奇异值不是放入对角矩阵,而是一个列向量中,所以需要自己将其变换为对角矩阵
	}
	outImage = U*W_*V;
	//outImage.convertTo(outImage, CV_8UC1);
	return outImage;
}

RobinsonFilter.h

#pragma once
#include<opencv2/opencv.hpp>
#include<iostream>
#include<vector>
#include<numeric>

#define KROBINSONFILTERPARA 0.7

class RobinsonFilter
{
public:
	RobinsonFilter();
	~RobinsonFilter();
	void Robinson_Guard(cv::Mat src, cv::Mat dst, int kernalsize);
};

RobinsonFilter.cpp

#include"RobinsonFilter.h"

RobinsonFilter::RobinsonFilter()
{

}

RobinsonFilter::~RobinsonFilter()
{

}


void RobinsonFilter::Robinson_Guard(cv::Mat src, cv::Mat dst, int kernalsize)
{
	std::vector<double> tempdata, borderdata;
	tempdata.clear();
	borderdata.clear();
	int ksize = 0;

	//归一化0-1之间,减小方差影响
	src.convertTo(src, CV_64FC1, 1.0 / 255.0);

	if (kernalsize % 2 == 0)
	{
		ksize = kernalsize / 2;
	}
	else
	{
		ksize = (kernalsize - 1) / 2;
	}
	if (kernalsize>src.rows || kernalsize>src.cols)
		std::cout << "核输入过大" << std::endl;

	for (int i = ksize; i < src.rows - ksize; i++)
	{
		double* data = src.ptr<double>(i);
		double* datadst = dst.ptr<double>(i);
		for (int j = ksize; j < src.cols - ksize; j++)
		{
			//centerpix = data[j];
			/*边缘区域分成四个区域计算*/
			borderdata.clear();
			for (int bl = i - ksize; bl < i + ksize; ++bl)
			{
				borderdata.push_back(src.at<double>(bl, j - ksize));
			}
			for (int bl = i - ksize + 1; bl < i + ksize + 1; ++bl)
			{
				borderdata.push_back(src.at<double>(bl, j + ksize));
			}
			for (int bk = j - ksize + 1; bk < j + ksize + 1; ++bk)
			{
				borderdata.push_back(src.at<double>(i - ksize, bk));
			}
			for (int bk = j - ksize; bk < j + ksize; ++bk)
			{
				borderdata.push_back(src.at<double>(i + ksize, bk));
			}
			double sum = std::accumulate(std::begin(borderdata), std::end(borderdata), 0.0);
			double mean = sum / borderdata.size(); //均值
			
			double accum = 0.0;
			std::for_each(std::begin(borderdata), std::end(borderdata), [&](const double d) {
				accum += (d - mean)*(d - mean);
			});

			double stdev = sqrt(accum / (borderdata.size() - 1)); //方差
			//均值,标准差
			//均值-k*std   均值+k*std k=0.7
			double tempLittle = mean - KROBINSONFILTERPARA*stdev;
			double tempBig = mean + KROBINSONFILTERPARA*stdev;

			if (src.ptr<double>(i)[j] > tempBig)
			{
				datadst[j] = src.ptr<double>(i)[j] - tempBig;
			}
			else if (src.ptr<double>(i)[j] < tempLittle)
			{
				datadst[j] = tempLittle - src.ptr<double>(i)[j];
			}
			else
			{
				datadst[j] = 0.0;
			}
						
		}
	}

}



LCadaptiveThreshold.h

#pragma once
#include<opencv2/opencv.hpp>
#include<iostream>
#include<vector>
#include<numeric>
#define KLCPARA 5
#define BORDERSIZE 2   //边缘,从第四行第四列开始
#define KLCPARA 0.7


class LCAdaptiveThreshold
{
public:
	LCAdaptiveThreshold();
	~LCAdaptiveThreshold();
	cv::Mat LCAdTh(cv::Mat imgEn, cv::Mat imgFilter);
private:
	std::vector<cv::Point> LCPointVec;
	std::vector<int> ReservedPointVec;
	std::vector<double> AlphaVec;
	std::vector<double> LCValVec;
	float TVal;

};

LCadaptiveThreshold.cpp

#include"LCadaptiveThreshold.h"

LCAdaptiveThreshold::LCAdaptiveThreshold()
{

}
LCAdaptiveThreshold::~LCAdaptiveThreshold()
{

}


cv::Mat LCAdaptiveThreshold::LCAdTh(cv::Mat imgEn, cv::Mat imgFilter)
{
	cv::Mat finalImg = cv::Mat::zeros(cv::Size(imgEn.cols, imgEn.rows), CV_8U);
	double LCVal = 0.0;
	double LCMin = 999.0, LCMax = 0.0;
	imgEn.convertTo(imgEn, CV_64FC1, 1.0 / 255.0);
	double imgFilMax, imgFilMin;
	cv::Point pt_min, pt_max;
	cv::minMaxLoc(imgFilter, &imgFilMin, &imgFilMax, &pt_min, &pt_max);
	for (int i = BORDERSIZE; i < imgFilter.rows - BORDERSIZE; i++)
	{
		for (int j = BORDERSIZE; j < imgFilter.cols - BORDERSIZE; j++)
		{
			double tempT, tempB;
			if (imgFilter.ptr<double>(i)[j]>(imgFilMax/2))
			{
				tempT = imgEn.ptr<double>(i - 1)[j - 1] + imgEn.ptr<double>(i - 1)[j] + imgEn.ptr<double>(i - 1)[j + 1] +
					imgEn.ptr<double>(i)[j - 1] + imgEn.ptr<double>(i)[j] + imgEn.ptr<double>(i)[j + 1] +
					imgEn.ptr<double>(i + 1)[j - 1] + imgEn.ptr<double>(i + 1)[j] + imgEn.ptr<double>(i + 1)[j + 1];

				tempB= imgEn.ptr<double>(i - 2)[j - 2] + imgEn.ptr<double>(i - 2)[j - 1] + imgEn.ptr<double>(i - 2)[j] +
					imgEn.ptr<double>(i - 2)[j + 1] + imgEn.ptr<double>(i - 2)[j + 2] + imgEn.ptr<double>(i - 1)[j + 2] +
					imgEn.ptr<double>(i)[j + 2] + imgEn.ptr<double>(i + 1)[j + 2] + imgEn.ptr<double>(i + 2)[j + 2] +
					imgEn.ptr<double>(i + 2)[j + 1] + imgEn.ptr<double>(i + 2)[j] + imgEn.ptr<double>(i + 2)[j - 1] +
					imgEn.ptr<double>(i + 2)[j - 2] + imgEn.ptr<double>(i + 1)[j - 2] + imgEn.ptr<double>(i)[j  - 2] +
					imgEn.ptr<double>(i - 1)[j - 2];
				LCVal = cv::abs((tempT / 9 - tempB / 16) / (tempB / 16));
				LCPointVec.push_back(cv::Point(j, i));
				LCValVec.push_back(LCVal);
				if (LCMin > LCVal)
				{
					LCMin = LCVal;
				}
				if (LCMax < LCVal)
				{
					LCMax = LCVal;
				}
					
			}
		}
	}
	for (int i = 0; i < LCValVec.size(); i++)
	{
		double tempAlpha = 0.0;
		tempAlpha = ((LCValVec[i] - LCMin) / (LCMax - LCMin))*LCMax;
		AlphaVec.push_back(tempAlpha);
	}
	double sum = std::accumulate(std::begin(AlphaVec), std::end(AlphaVec), 0.0);
	double mean = sum / AlphaVec.size(); //均值

	double accum = 0.0;
	std::for_each(std::begin(AlphaVec), std::end(AlphaVec), [&](const double d) {
		accum += (d - mean)*(d - mean);
	});

	double stdev = sqrt(accum / (AlphaVec.size() - 1)); //方差
	double YuZhi = mean + KLCPARA*stdev;


	for (int i = 0; i < LCValVec.size(); i++)
	{
		if (LCValVec[i] > YuZhi)
		{
			ReservedPointVec.push_back(i);
			
		}
	}
	int cnt = 0;

	for (int i = 0; i < ReservedPointVec.size(); i++)
	{

		cnt++;
		finalImg.ptr<int>(LCPointVec[ReservedPointVec[i]].y)[LCPointVec[ReservedPointVec[i]].x] = 1;
		//std::cout << "x:" << LCPointVec[ReservedPointVec[i]].x << std::endl;
		//std::cout << "y:" << LCPointVec[ReservedPointVec[i]].y << std::endl;
		
	}

	

	finalImg.convertTo(finalImg, CV_8UC1,255);
	return finalImg;
}

testFunc.cpp

#include"imageEnhance.h"
#include"RobinsonFilter.h"
#include"LCadaptiveThreshold.h"


int main()
{
	

	imageEnhanceSVD pre;
	RobinsonFilter Rob;
	LCAdaptiveThreshold LCAT;
	//cv::Mat frame = cv::imread("E:\\dataSet\\dxm\\ceshi.png");
	cv::Mat frame = cv::imread("E:\\dataSet\\155\\2-00012901.jpg");
	cv::Mat frame_;
	cv::cvtColor(frame, frame, cv::COLOR_BGR2GRAY);
	//cv::imshow("ori", frame);
	//for (int i = 0; i < 9; i++)
	//{
	//	for (int j = 0; j < 9; j++)
	//	{
	//		std::cout << int(frame_.ptr<uchar>(i)[j]) << " ";
	//	}
	//	std::cout << std::endl;
	//}
	//std::cout << std::endl;
	//for (int i = 0; i < 9; i++)
	//{
	//	for (int j = 0; j < 9; j++)
	//	{
	//		std::cout << int(frame.ptr<uchar>(i)[j])<<" ";
	//	}
	//	std::cout<<std::endl;
	//}
	cv::Mat RBGImg = cv::Mat::zeros(cv::Size(frame.cols,frame.rows),CV_64FC1);
	//cv::Mat SVDImg = cv::Mat::zeros(cv::Size(frame.cols, frame.rows), CV_64FC1);
	//SVDImg = pre.preProcessSVD(frame);


#if 1
	cv::Mat SVDImg = frame.clone();
	clock_t begin = clock();
	Rob.Robinson_Guard(SVDImg, RBGImg, 5);
	clock_t end = clock();
	std::cout << (double)(end - begin) << std::endl;
	//cv::namedWindow("RBGImg", cv::WINDOW_NORMAL);
	//RBGImg.convertTo(RBGImg, CV_8UC1,255);
	//cv::imshow("RBGImg", RBGImg);
	//cv::waitKey(0);
	clock_t begin1 = clock();
	cv::Mat outImg = LCAT.LCAdTh(SVDImg, RBGImg);
	clock_t end1 = clock();
	std::cout << (double)(end1 - begin1) << std::endl;
	cv::namedWindow("outImg", cv::WINDOW_NORMAL);
	cv::imshow("outImg", outImg);
	cv::waitKey(0);
#endif
	
	return 0;
}

在这里插入图片描述
有一定的效果,但是SVD的效果不明显,时间上SVD分解过长,RobinsonFilter滤波器的时间也达不到10ms以内,LC阈值分割方法可以借鉴。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dx0014

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值