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