时域去燥的简单尝试

本文探讨了时域信号去噪的基本方法,通过实例分析展示了如何应用这些方法去除噪声,提升信号质量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//test 
#include "deNoise.h"

#define  TMP_SIZE  5
#define  MAX_SAD_THRESH 3

int main()
{   
	VideoCapture capture;
	if (!capture.isOpened())
	{   
		int width   = 1920;
		int height  = 1080;
		int picSize = width * height;
		capture.open(0);//创建视频流对象//这儿0一般时电脑自带的摄像头,其他数字则时外接摄像头的ID号。
		capture.set(CV_CAP_PROP_FRAME_WIDTH, width);
	    capture.set(CV_CAP_PROP_FRAME_HEIGHT, height);

		width  =  capture.get(CV_CAP_PROP_FRAME_WIDTH);
		height =  capture.get(CV_CAP_PROP_FRAME_HEIGHT);
		picSize = width * height;
		int histWidth  = 512;
		int histHeight = 400;
		/*设置摄像头参数 不要随意修改
		capture.set(CV_CAP_PROP_FRAME_WIDTH, 1080);//宽度
		capture.set(CV_CAP_PROP_FRAME_HEIGHT, 960);//高度
		capture.set(CV_CAP_PROP_FPS, 30);//帧数
		capture.set(CV_CAP_PROP_BRIGHTNESS, 1);//亮度 1
		capture.set(CV_CAP_PROP_CONTRAST,40);//对比度 40
		capture.set(CV_CAP_PROP_SATURATION, 50);//饱和度 50
		capture.set(CV_CAP_PROP_HUE, 50);//色调 50
		capture.set(CV_CAP_PROP_EXPOSURE, 50);//曝光 50
		*/
		VideoWriter outcapture;
		//视频输出
		//第一个参数存的文件名和格式,第二个时编码方式,第三个是帧率大小,第四个是保存视频的大小

		outcapture.open("3.wmv", CV_FOURCC('M', 'P', '4', '2'), 25.0, Size(width, height));

		Mat frame;

		if (capture.isOpened())
		{
			capture.set(cv::CAP_PROP_SETTINGS, 1);//打开设置模式
		}

		int frameIndex = 0;
		vector<unsigned char*> tmpImg;
		tmpImg.clear();
		tmpImg.reserve(TMP_SIZE);
		Mat dstShow(height, width, CV_8UC3);
		Mat difShow(height, width, CV_8UC3);

		unsigned char* src = (unsigned char*)malloc(TMP_SIZE * 3 * picSize * sizeof(unsigned char));
		unsigned char* dst = (unsigned char*)malloc(3 * picSize * sizeof(unsigned char));
		unsigned char* dif = (unsigned char*)malloc(3 * picSize * sizeof(unsigned char));
		signed char  * signedDif = (signed char*)malloc(3 * picSize * sizeof(signed char));
		signed char  * refineDif = (signed char*)malloc(3 * picSize * sizeof(signed char));

		unsigned char* srcAddr[TMP_SIZE] = { 0 };

		for (int i = 0; i < TMP_SIZE; i++)
		{
			srcAddr[i] = src + i * 3 * picSize;
			tmpImg.push_back(srcAddr[i]);
		}
		int headIdx = 0;
		unsigned char* tmp = NULL;
		while (1)
		{   
			capture >> frame;

			if (frameIndex < TMP_SIZE)
			{
				cvtColorBgrC2RgbP(tmpImg[frameIndex], frame.data, width, height);//push back
				memcpy(dst, tmpImg[frameIndex], 3 * picSize);
			}
			else
			{
				buffer_left_move(tmpImg, TMP_SIZE);
				cvtColorBgrC2RgbP(tmpImg[TMP_SIZE - 1], frame.data, width, height);//push back
				//simpleDeNoise(dst, tmpImg, TMP_SIZE, width, height);
				weightingDeNoise(dst, tmpImg, TMP_SIZE, width, height);
// 				calSadImg(dif, signedDif, dst, src, width, height);
// 
// 				float fre[256] = { 0.f };
// 				float sumFre[256] = { 0.f };
// 				calFreImg(fre, sumFre, dif, width, height);
// 				int  noiseLevel = calNoiseLevel(sumFre, 0.8);
// 
// 				refineDifImg(refineDif, signedDif, fre, width, height, noiseLevel);
// 				imgAdd(dst, src, refineDif, width, height);
			}

			//outcapture.write(frame);//outcapture << frame;	两种方式都可以保存视频
			frameIndex ++;

			cvtColorRgbP2BgrC(dstShow.data, dst, width, height);
			cvtColorRgbP2BgrC(dstShow.data, dst, width, height);
			cvtColorRgbP2BgrC(difShow.data, dif, width, height);
			Mat histImage(histHeight, histWidth, CV_8UC3, Scalar(0, 0, 0));
			calHist(difShow, histImage, histWidth, histHeight);

			namedWindow("src", 1);
			imshow("src", frame);
			namedWindow("dst", 1);
			imshow("dst", dstShow);
			namedWindow("dst", 1);
			imshow("dst", dstShow);
			namedWindow("dif", 1);
			imshow("dif", difShow);
			namedWindow("hist", 1);
			imshow("hist", histImage);
			waitKey(10);
		}
	}
}

// 函数实现如下
void simpleDeNoise(unsigned char* dst, vector<unsigned char*> tmperal, int n, int width, int height)
{
	int picSize = width * height;
	float factor = 1.f / n;

	for (int h = 0; h < height; h ++)
	{
		for (int w = 0; w < width; w ++)
		{
			int pixSum[3] = { 0 };
			for (int i = 0; i < n; i ++)
			{
				pixSum[0] += tmperal[i][w];
				pixSum[1] += tmperal[i][w + picSize];
				pixSum[2] += tmperal[i][w + 2 * picSize];
			}
			dst[w]               = (unsigned char)(factor * pixSum[0]);
			dst[picSize + w]     = (unsigned char)(factor * pixSum[1]);
			dst[2 * picSize + w] = (unsigned char)(factor * pixSum[2]);
		}
		dst += width;
		for (int i = 0; i < n; i ++)
		{
			tmperal[i] += width;
		}
	}
}

void weightingDeNoise(unsigned char* dst, vector<unsigned char*> tmperal, int n, int width, int height)
{
	int picSize = width * height;
	float factor = 1.f / n;

	for (int h = 0; h < height; h++)
	{
		for (int w = 0; w < width; w++)
		{   
			unsigned char srcCur[3] = { tmperal[n - 1][w], tmperal[n - 1][w + picSize], tmperal[n - 1][w + 2 * picSize] };
			int pixSum[3] = { 0 };
			float weight[TMP_SIZE] = { 0 };
			float weightsum = 0;

			for (int i = 0; i < n; i++)
			{   
				unsigned char srcPre[3] = { tmperal[i][w], tmperal[i][w + picSize], tmperal[i][w + 2 * picSize] };
				weight[i] = calSimilarity(srcCur, srcPre);
				weightsum += weight[i];
				pixSum[0] += weight[i] * srcPre[0];
				pixSum[1] += weight[i] * srcPre[1];
				pixSum[2] += weight[i] * srcPre[2];
			}

			factor = 1 / weightsum;
			dst[w]               = (unsigned char)(factor * pixSum[0]);
			dst[picSize + w]     = (unsigned char)(factor * pixSum[1]);
			dst[2 * picSize + w] = (unsigned char)(factor * pixSum[2]);
		}
		dst += width;
		for (int i = 0; i < n; i++)
		{
			tmperal[i] += width;
		}
	}
}

float calSimilarity(unsigned char  src1[3], unsigned  char src2[3])
{
	int sad = 0;

	for (int i = 0; i < 3; i++)
	{
		sad += abs(src1[i] - src2[i]);
	}

	float weight = (1.f * MAX_SAD_THRESH / sad);
	weight = weight > 1 ? 1 : weight;
	return weight;
}

void  buffer_left_move(vector<unsigned char*> &buffer, int buf_len)
{
	int i;
	unsigned char* tmp = buffer[0];
	for (i = 1; i < buf_len; i++)
	{
		buffer[i - 1] = buffer[i];
	}
	buffer[buf_len - 1] = tmp;
}


void calFreImg(float* fre, float *sumFre, unsigned char* src, int width, int height)
{
	int picSize = 3 * width * height;
	int numCount[256] = { 0 };
	float factor = 1.f / picSize;

	for (int i = 0; i < picSize; i++)
	{
		numCount[src[i]]++;
	}
	for (int i = 0; i < 256; i++)
	{
		fre[i] = numCount[i] * factor;
	}

	sumFre[0] = fre[0];
	for (int i = 1; i < 256; i++)
	{
		sumFre[i] += sumFre[i - 1] + fre[i];
	}
}

int calNoiseLevel(float* sumFree, float freThresh)
{
	for (int i = 1; i < 256; i++)
	{
		if (sumFree[i] > freThresh)
		{
			return i;
		}
	}
	return 255;
}

void refineDifImg(signed char* dst, signed char* src, float *fre, int width, int height, int thresh)
{
	int picSize = 3 * width * height;

	for (int i = 0; i < picSize; i++)
	{
		dst[i] = abs(src[i]) > thresh ? 0 : src[i];
		//dst[i] = (signed char)(src[i] * fre[src[i]]);
	}
}

void imgAdd(unsigned char* dst, unsigned char* src1, signed char* src2, int width, int height)
{
	int picSize = 3 * width * height;

	for (int i = 0; i < picSize; i++)
	{   
		int tmp = src1[i] + src2[i];
		dst[i] = tmp < 0 ? 0 : tmp > 255 ? 255 : tmp;
	}
}

void imgSub(unsigned char* dst, unsigned char* src1, unsigned char* src2, int width, int height)
{
	int picSize = 3 * width * height;

	for (int i = 0; i < picSize; i++)
	{
		dst[i] = src1[i] - src2[i];
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值