三维直方图

 

本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/koriya/archive/2008/11/21/3347369.aspx

 

三維直方圖擷取
/****************************
* change image histogram example
* date:08-11-1
* author: wml
* copyright:1.0
*****************************/
#include <cv.h>
#include <highgui.h>
#include <cvaux.h>
#include <cxcore.h>
#include <iostream.h>
#include <string.h>
#include <stdio.h>

#pragma comment(lib,"cv")
#pragma comment(lib,"cvaux")
#pragma comment(lib,"cxcore")
#pragma comment(lib,"highgui")


int Histogram3DBlock[3] = {256,256,256};
float HistogramRange1[6]={0,255,0,255,0,255};
float *HistogramRange[3]={&HistogramRange1[0],&HistogramRange1[2],&HistogramRange1[4]};

void Print3DHistogram(CvHistogram *Histogram,int BlockSize);

int main()
{
     CvHistogram *Histogram1;
     IplImage *Image1=cvLoadImage("D://image test c++//histrogm3/1.bmp",1);
     IplImage *RedImage=cvCreateImage(cvGetSize(Image1),8,1);
     IplImage *GreenImage=cvCreateImage(cvGetSize(Image1),8,1);
     IplImage *BlueImage=cvCreateImage(cvGetSize(Image1),8,1);
     IplImage *ImageArray[3]={RedImage,GreenImage,BlueImage};

     cvSplit(Image1,BlueImage,GreenImage,RedImage,0);
     Histogram1 = cvCreateHist(3,Histogram3DBlock,CV_HIST_SPARSE,HistogramRange);

     cvCalcHist(ImageArray,Histogram1);

     printf("3D Historgram Data/n");
     Print3DHistogram(Histogram1,256);

     cvNamedWindow("Riverbank",1);
     cvShowImage("Riverbank",Image1);

     cvWaitKey(0);
}

 

void Print3DHistogram(CvHistogram *Histogram,int BlockSize)
{
    for(int i=0;i<BlockSize;i++)
     {
        for(int j=0;j<BlockSize;j++)
         {
            for(int k=0;k<BlockSize;k++)
             {
                if(cvQueryHistValue_3D(Histogram,i,j,k)>10)
                 {
                     printf("%5.f",cvQueryHistValue_3D(Histogram,i,j,k));
                 }
             }
         }
     }
}

 

面是三個維度的統計直方圖,分別為R維度,G維度,B維度,並且分別被量化成256等分的區塊,同樣的,也是使用LUT的方法,由於這個統計直方圖非常的大,它所佔的區域為256*256*256的大小,而實際上累積的分佈只有一點點,所以說,對於高維度的統計直方圖就要用到稀疏矩陣,要不然會浪放大量的記憶體空間,但是對於多維度的圖表呈現,OpenCV最多也只能支援到一維的方式,二維的方式可以用OpenGL(glut)呈現,當然高的維度本來就很難用視覺化的方式呈現.

### 关于三维直方图的实现与使用 三维直方图是一种用于表示数据分布的方法,通常应用于图像处理领域中的颜色空间分析。它通过统计三个维度上的像素值频率来描述图像的颜色特征[^1]。 #### Python 实现三维直方图 以下是基于 NumPy 和 Matplotlib 的简单三维直方图实现: ```python import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D def create_3d_histogram(image, bins=8): """ 创建一个 RGB 图像的三维直方图。 参数: image (numpy.ndarray): 输入的 RGB 图像数组。 bins (int): 每个通道的分箱数量。 返回: hist (numpy.ndarray): 计算得到的三维直方图。 """ # 将图像转换为浮点数并归一化到 [0, 1] image = image.astype("float") / 255.0 # 获取 R、G、B 通道 r, g, b = cv2.split(image) # 使用 numpy.histogramdd 函数计算三维直方图 hist, _ = np.histogramdd(np.vstack((r.flatten(), g.flatten(), b.flatten())).T, bins=(bins, bins, bins), range=((0, 1), (0, 1), (0, 1))) return hist # 可视化三维直方图 def plot_3d_histogram(hist): fig = plt.figure() ax = fig.add_subplot(111, projection='3d') # 构建网格坐标 x_edges, y_edges, z_edges = np.indices(np.array(hist.shape) + 1).reshape(3, -1) * (1/hist.shape[0]) # 提取柱体位置和大小 colors = hist.ravel()[:, None] * plt.cm.viridis_r(np.linspace(0, 1, hist.size)) rect = np.c_[x_edges[:-1], y_edges[:-1], z_edges[:-1], x_edges[1:], y_edges[1:], z_edges[1:]].reshape(-1, 6) for idx in range(len(rect)): xx = [[rect[idx][0], rect[idx][0], rect[idx][3], rect[idx][3]], [rect[idx][0], rect[idx][0], rect[idx][3], rect[idx][3]]] yy = [[rect[idx][1], rect[idx][4], rect[idx][4], rect[idx][1]], [rect[idx][1], rect[idx][4], rect[idx][4], rect[idx][1]]] zz = [[rect[idx][2], rect[idx][2], rect[idx][2], rect[idx][2]], [rect[idx][5], rect[idx][5], rect[idx][5], rect[idx][5]]] ax.plot_surface(xx, yy, zz, color=colors[idx]) plt.show() # 示例调用 image = cv2.imread('example.jpg') # 替换为实际图片路径 histogram = create_3d_histogram(image) plot_3d_histogram(histogram) ``` 此代码片段展示了如何利用 `numpy` 库创建三维直方图,并借助 `matplotlib` 进行可视化[^1]。 #### OpenCV 中的应用 OpenCV 是一种流行的计算机视觉库,支持多种图像处理功能。对于三维直方图,可以使用其内置函数 `cv2.calcHist()` 来简化流程。然而需要注意的是,该函数默认仅适用于单通道或双通道直方图。如果要生成完整的三通道直方图,则需手动组合多个二维直方图的结果[^1]。 #### 数学基础 假设输入图像具有 \( n \times m \) 像素分辨率,在 RGB 颜色模型下每一点由红 (\(R\))、绿 (\(G\)) 和蓝 (\(B\)) 组件定义。构建三维直方图的过程涉及将这些组件映射至离散区间 [\([a,b]\)] 并记录落入各子区间的样本计数。最终形成一个形状为 \( k_R \times k_G \times k_B \) 的张量结构,其中 \(k_i\) 表示第 i 色彩轴划分的数量。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值