【圖像處理】retinex單尺度多線程c++實現

【圖像處理】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

可以看出多線程還是要快一些。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章