【圖像處理】retinex單尺度多線程c++實現
上一篇實現了該算法,本文以多線程形式實現。
調用接口:
cv::Mat retinex_multithread(const cv::Mat& src);
效果請參看上一篇實現。
retinex單尺度c++實現
本文完整代碼如下:
#include <iostream>
#include <opencv2/opencv.hpp>
#include <thread>
#include <assert.h>
/*
* 多通道或者單通道
*/
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;
}
/*
* 單通道retinex
*/
void retinex_1(const cv::Mat& src, cv::Mat* dst)
{
assert(src.type() == CV_8UC1);
cv::Mat src_float;
src.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, src.type());
cv::equalizeHist(r, *dst);
}
/*
* 多線程實現
*/
cv::Mat retinex_multithread(const cv::Mat& src)
{
cv::Mat dst;
if (src.channels() == 1){
retinex_1(src, &dst);
return dst;
}
std::vector<cv::Mat> bgr;
cv::split(src, bgr);
cv::Mat mat[3];
std::thread g_channel = std::thread(retinex_1, bgr[1], &mat[1]);
std::thread b_channel = std::thread(retinex_1, bgr[2], &mat[2]);
retinex_1(bgr[0], &mat[0]);
if (g_channel.joinable()) g_channel.join();
if (b_channel.joinable()) b_channel.join();
cv::merge(mat, 3, dst);
return dst;
}
int main()
{
int n = 0;
double t_1 = 0.0, t_2 = 0.0;
cv::Mat input = cv::imread("ori.jpg");
while (n < 100)
{
double t1 = cv::getTickCount();
cv::Mat dst = retinex_multithread(input);
t1 = cv::getTickCount() - t1;
t_1 += t1 * 1000 / cv::getTickFrequency();
double t2 = cv::getTickCount();
cv::Mat dst2 = retinex_0(input);
t2 = cv::getTickCount() - t2;
t_2 += t2 * 1000 / cv::getTickFrequency();
n++;
}
printf("average time: \n");
printf("multi thread retinex: %.3fms\n", t_1/100);
printf("retinex: %.3fms\n", t_2/100);
system("pause");
return 0;
}
圖像分辨率位328 x 500 x 3。
輸出時間:
average time:
multi thread retinex: 246.299ms
retinex: 456.063ms
可以看出多線程還是要快一些。