本章主要内容有图像的直方图计算、直方图均衡化、图像大小变换及旋转(当然了,基于CUDA)。
一、直方图计算
OpenCV GPU版本计算直方图的时候只能是单通道(这点跟CPU版本不一样),那么如果是多通道怎么办呢,一个一个计算呗。
主要API:
cuda::split() //通道分离
cuda::calcHist() //计算直方图
#include<opencv2/opencv.hpp>
#include<opencv2/cudaimgproc.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
Mat input_image = imread("F:/test/lena.jpg");
if (input_image.empty())
{
cout << "the image is not exist..." << endl;
return -1;
}
cuda::GpuMat image(input_image),hist;
/*-----直方图计算------*/
vector<cuda::GpuMat>mv;
cuda::split(image, mv);//通道分离
cuda::calcHist(mv[2], hist);
Mat hist_host;
hist.download(hist_host);
for (int i = 0; i < hist_host.cols; i++)
{
int pv = hist_host.at<int>(0, i);
cout << "个数:" << pv << " " << "像素值" << i << endl;
}
return 0;
}
打印结果:
有了这个东西,就可以绘制直方图。
二、直方图均衡化
直方图均衡化比较受限的一点是,它只支持单通,不支持多通道,所以依旧要通道分离,但是这个通道分离不是分离BGR,而是分离HSV,其中的“V”代表了亮度,我们就是要对V通道进行均衡化。
主要有以下步骤:
1)BGR转HSV;
2)分离HSV中的V通道;
3)对V通道做直方图均衡化;
4)混合HSV(V是均衡化后的结果);
5)HSV转BGR。
代码:
/*-----直方图均衡化-----*/
//转成HSV通道
cuda::GpuMat hsv;
cuda::cvtColor(image, hsv, COLOR_BGR2HSV);
vector<cuda::GpuMat>eq_mv;
cuda::split(hsv, eq_mv);//通道分离
cuda::equalizeHist(eq_mv[2], eq_mv[2]);//直方图均衡化
cuda::merge(eq_mv, hsv);//重新混合所有通道
cuda::cvtColor(hsv, hsv, COLOR_HSV2BGR);//把HSV转回BGR
Mat hsv_host;
hsv.download(hsv_host);
imshow("input image", input_image);
imshow("eq-hist", hsv_host);
waitKey(0);
结果:
三、图像Resize和旋转
这个操作跟OpenCV CPU版的其实没什么两样,会的人自然懂,不会的人需要学一下CPU版的,下面直接上代码:
1)resize:
cuda::GpuMat dst;
Mat resize_dst;
cuda::resize(image, dst, Size(0, 0), 1.2, 1.2,INTER_CUBIC);//resize
dst.download(resize_dst);
imshow("resize image", resize_dst);
waitKey(0);
结果:
2)旋转:
cuda::GpuMat rota;
Mat rota_host;
int center_x = input_image.rows / 2;
int center_y = input_image.cols / 2;
Mat M = getRotationMatrix2D(Point(center_x, center_y), 45, 1.0);
cuda::warpAffine(image, rota, M, image.size());
rota.download(rota_host);
imshow("rota image", rota_host);
waitKey(0);
结果:
可以看到,确实是变换了吧,其实,本章的所有内容都是可以用在图像增强里面的,也主要是为了深度学习打下一个基础。
下面附上所有代码:
#include<opencv2/opencv.hpp>
#include<opencv2/cudaimgproc.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
Mat input_image = imread("F:/test/lena.jpg");
if (input_image.empty())
{
cout << "the image is not exist..." << endl;
return -1;
}
cuda::GpuMat image(input_image),hist;
/*-----直方图计算------*/
vector<cuda::GpuMat>mv;
cuda::split(image, mv);//通道分离
cuda::calcHist(mv[2], hist);
Mat hist_host;
hist.download(hist_host);
for (int i = 0; i < hist_host.cols; i++)
{
int pv = hist_host.at<int>(0, i);
cout << "个数:" << pv << " " << "像素值" << i << endl;
}
/*-----直方图均衡化-----*/
//转成HSV通道
cuda::GpuMat hsv;
cuda::cvtColor(image, hsv, COLOR_BGR2HSV);
vector<cuda::GpuMat>eq_mv;
cuda::split(hsv, eq_mv);//通道分离
cuda::equalizeHist(eq_mv[2], eq_mv[2]);//直方图均衡化
cuda::merge(eq_mv, hsv);//重新混合所有通道
cuda::cvtColor(hsv, hsv, COLOR_HSV2BGR);//把HSV转回BGR
Mat hsv_host;
hsv.download(hsv_host);
imshow("input image", input_image);
imshow("eq-hist", hsv_host);
/*-----图像resize-----*/
cuda::GpuMat dst;
Mat resize_dst;
cuda::resize(image, dst, Size(0, 0), 1.2, 1.2,INTER_CUBIC);//resize
dst.download(resize_dst);
imshow("resize image", resize_dst);
/*-----图像旋转-----*/
cuda::GpuMat rota;
Mat rota_host;
int center_x = input_image.rows / 2;
int center_y = input_image.cols / 2;
Mat M = getRotationMatrix2D(Point(center_x, center_y), 45, 1.0);
cuda::warpAffine(image, rota, M, image.size());
rota.download(rota_host);
imshow("rota image", rota_host);
waitKey(0);
return 0;
}