欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-07-06 12:16:56
...

低小慢目标光电探测技术研究论文仿真
低小慢目标光电探测技术研究论文仿真
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阈值分割方法可以借鉴。

相关标签: 仿真