【圖像處理】retinex單尺度c++實現
原理網上很多,實現版本也很多,自己也想實現下。
本文基於c++和opencv實現。
#include <iostream>
#include <opencv2/opencv.hpp>
#include <vector>
cv::Mat retinex_0(const cv::Mat& src)
{
std::vector<cv::Mat> bgr;
cv::split(src, bgr);
std::vector<cv::Mat> rgb;
for (auto iter = bgr.begin(); iter != bgr.end(); iter++)
{
cv::Mat src_float;
(*iter).convertTo(src_float, CV_32F);
cv::Mat low_frequency;
cv::GaussianBlur(src_float, low_frequency, cv::Size(0, 0), 200);
cv::log(src_float, src_float);
cv::log(low_frequency, low_frequency);
cv::Mat r = src_float - low_frequency;
cv::exp(r, r);
cv::normalize(r, r, 0, 255, cv::NORM_MINMAX, CV_8UC1);
cv::equalizeHist(r, r);
rgb.push_back(r);
}
cv::Mat dst;
cv::merge(rgb, dst);
return dst;
}
cv::Mat retinex_1(const cv::Mat& src)
{
cv::Mat src_float;
/*步驟1:轉成浮點型*/
src.convertTo(src_float, CV_32F);
cv::Mat low_frequency;
cv::GaussianBlur(src_float, low_frequency, cv::Size(0, 0), 300);
cv::log(src_float, src_float);
cv::log(low_frequency, low_frequency);
cv::Mat r = src_float - low_frequency;
cv::Mat dst;
cv::exp(r, dst);
cv::normalize(dst, dst, 0, 255, cv::NORM_MINMAX, src.type());
return dst;
}
int main()
{
cv::Mat input = cv::imread("4.jpg");
cv::Mat dst = retinex_0(input);
cv::imshow("original.jpg", input);
cv::imshow("retinex.jpg", dst);
cv::waitKey(0);
return 0;
}
原圖:
retinex輸出:
如果不加直方圖均衡cv::equalizeHist(r, r);效果似乎沒那麼明顯。。。