Ubuntu系统VScode实现opencv(c++)图像二维直方图
在数字图像处理中,二维直方图是一种强大的工具,用于同时分析图像中两个通道的像素值分布。与一维直方图(通常用于单通道图像)不同,二维直方图能够捕捉两个通道之间的关系,从而提供更丰富的图像特征信息。这种分析在许多应用中具有重要意义,例如图像分割、目标检测、特征匹配以及图像增强等。
二维直方图的应用
图像分割:通过分析两个通道的联合分布,可以更准确地识别和分离图像中的不同区域。例如,在医学图像中,二维直方图可以帮助区分不同的组织类型。
目标检测:在复杂背景中,某些目标可能具有独特的颜色特征。二维直方图可以用于描述这些特征,并帮助定位目标。
特征匹配:在图像配准或拼接中,二维直方图可以作为特征描述符,用于匹配图像之间的相似区域。
图像增强:通过分析两个通道的联合分布,可以设计更有效的增强算法,改善图像的视觉效果。
二维对应两个通道,应该有两个bins,分别对应两个通道的横坐标,以HSV格式的为例子,分为亮度与色域。
第一步是将输入的图片转到HSV格式:
cvtColor(image,image,COLOR_BGR2HSV);
定义所需要的参数:
const int hbins = 30,sbins = 32;int hist_bins[] = {hbins,sbins};float h_ranges[] = {0,180};float s_ranges[] = {0,256};const float* ranges[] = {h_ranges,s_ranges};int hs_channel[]={0,1};
hbins是亮度的横坐标,sbins是色度的横坐标 ,h_ranges是亮度像素的范围,s_ranges是色度像素的最大最小范围,hs_channel是用于标明通道的,0就是亮度通道,1就是色度通道。
整体代码如下:
void Demo::calicHist_2D_Demo(Mat &image)
{cvtColor(image,image,COLOR_BGR2HSV);// imshow("HSV",image);const int hbins = 30,sbins = 32;int hist_bins[] = {hbins,sbins};float h_ranges[] = {0,180};float s_ranges[] = {0,256};const float* ranges[] = {h_ranges,s_ranges};int hs_channel[]={0,1};Mat hs_hist;calcHist(&image,1,hs_channel,Mat(),hs_hist,2,hist_bins,ranges);// ---------- 1. 归一化到 0~255 ----------normalize(hs_hist, hs_hist, 0, 255, NORM_MINMAX);// ---------- 2. 生成可显示的 8 位单通道图 ----------Mat histImg(sbins, hbins, CV_8UC1);for (int y = 0; y < sbins; ++y){uchar* row = histImg.ptr<uchar>(y);for (int x = 0; x < hbins; ++x){row[x] = saturate_cast<uchar>(hs_hist.at<float>(y, x));}}// ---------- 3. 伪彩色增强 ----------Mat colorMap;applyColorMap(histImg, colorMap, COLORMAP_JET);// ---------- 4. 放大显示 ----------resize(colorMap, colorMap, Size(hbins * 10, sbins * 10), 0, 0, INTER_NEAREST);// ---------- 5. 显示 ----------imshow("H-S 2D Histogram", colorMap);waitKey(0);
}
由于这是二维直方图,所以呈现的效果就是色素块的堆积,越亮就代表出现的最多。