注:因图床原因,本文图片已挂
手机在暗光环境下拍照时,由于进光量不足,拍出的照片上经常会出现严重的彩色噪声,如下图所示:
这种彩色噪声极大地影响了图像的观感,所以必须去除。而要在手机上运行,算法也一定要轻量化。这里提出一种轻量级而且比较实用的去彩噪的方法:使用Guided Filter去噪。
算法的步骤如下:
- 将需要去噪的RGB图像(记为I)转换为YUV格式,记为I_YUV;
- 对I进行guided filter,I自己作为引导图像,得到滤波后的图像,记为I_gf;
- 将I_gf转换为YUV格式,记为I_gf_YUV;
- 使用I_YUV的Y通道替换I_gf_YUV的Y通道,得到新的YUV图像,记为I_Y_gf_UV;
- 将I_Y_gf_UV转换为RGB格式,即为去噪后图像。
去噪后的效果如下:
可以看到,除了颜色有一点冲淡外,去彩噪的效果相当显著。
测试代码如下:
// Win10 + Visual Studio Community 2017 + OpenCV 3.3.0
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/ximgproc.hpp"
#include <iostream>
void chromaNoiseReduction(const cv::Mat& src, cv::Mat& dst, int radius = 30, double eps = 0.03 * 255 * 255)
{
CV_Assert(src.type() == CV_8UC3);
CV_Assert(src.cols % 2 == 0 && src.rows % 2 == 0);
const cv::Mat& I = src;
// step 1. convert I to YUV format
cv::Mat I_YUV;
cv::cvtColor(I, I_YUV, cv::COLOR_BGR2YUV_I420);
// step 2. do guided filtering on I
cv::Mat I_gf;
cv::ximgproc::guidedFilter(I, I, I_gf, radius, eps);
// step 3. convert I_gf to YUV format
cv::Mat I_gf_YUV;
cv::cvtColor(I_gf, I_gf_YUV, cv::COLOR_BGR2YUV_I420);
// step 4. replace I_gf_YUV's Y channel with I_YUV's Y channel
cv::Mat I_Y_gf_UV = I_gf_YUV.clone();
memcpy(I_Y_gf_UV.data, I_YUV.data, I.cols * I.rows);
// step 5. convert I_Y_gf_UV to BGR, which is the result
cv::cvtColor(I_Y_gf_UV, dst, cv::COLOR_YUV2BGR_I420);
}
int main()
{
cv::Mat image = cv::imread("2.jpg");
if (image.empty())
{
std::cout << "Couldn't open file." << std::endl;
return -1;
}
cv::Mat result;
chromaNoiseReduction(image, result);
cv::imwrite("result.jpg", result);
return 0;
}