首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在c++中平平颜色直方图?

如何在c++中平平颜色直方图?
EN

Stack Overflow用户
提问于 2018-08-28 19:39:46
回答 2查看 1.2K关注 0票数 2

嗨,我用python编写了以下代码行:

代码语言:javascript
复制
# convert the image to HSV color-space
image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

# compute the color histogram
hist  = cv2.calcHist([image], [0, 1, 2], None, [bins, bins, bins], [5, 240, 5, 240, 5, 240])

# normalize the histogram
cv2.normalize(hist, hist)

# return the histogram
return hist.flatten()

我现在正试图用c++重写它。我在calculation.html找到了一个很好的例子

我现在面临的问题是在c++中扁平hist,例如在python中,code.This是python (512,)中扁平hist输出的形状。对于如何在c++中获得相同的结果,有什么想法吗?

(编辑)到目前为止的c++代码。

大小(500,500);图像= imread("C:\johan.jpg",IMREAD_COLOR);

代码语言:javascript
复制
 resize(image,image,size);//resize image

 cvtColor(image, image, CV_BGR2HSV);
// Separate the image in 3 places ( H, S and V )
 vector<Mat> bgr_planes;
 split(image, bgr_planes );

 vector<Mat> hist_flat;

 // Establish the number of bins
 int histSize = 256;

 // Set the ranges ( for H,S,V) )
 float range[] = {5, 240} ;
 const float* histRange = { range };

 bool uniform = true; bool accumulate = false;

 Mat b_hist, g_hist, r_hist;

 cout << " Working fine Johan...";

 // Compute the histograms:
 calcHist( &bgr_planes[0], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate );
 calcHist( &bgr_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate );
 calcHist( &bgr_planes[2], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate );
 //calcHist( &image,3, 0, Mat(), hist_flat, 1, &histSize, &histRange, uniform, accumulate );



 // Draw the histograms for B, G and R
 int hist_w = 512; int hist_h = 400;
 int bin_w = cvRound( (double) hist_w/histSize );



 Mat histImage(hist_h,hist_w, CV_8UC3, Scalar(0,0,0));

 // Normalize the result to [ 0, histImage.rows ]
 normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
 normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
 normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );



 // Draw for each channel
 for( int i = 1; i < histSize; i++ )
 {
     line( histImage, Point( bin_w*(i-1), hist_h - cvRound(b_hist.at<float>(i-1)) ) ,
                      Point( bin_w*(i), hist_h - cvRound(b_hist.at<float>(i)) ),
                      Scalar( 255, 0, 0), 2, 8, 0  );
     line( histImage, Point( bin_w*(i-1), hist_h - cvRound(g_hist.at<float>(i-1)) ) ,
                      Point( bin_w*(i), hist_h - cvRound(g_hist.at<float>(i)) ),
                      Scalar( 0, 255, 0), 2, 8, 0  );
     line( histImage, Point( bin_w*(i-1), hist_h - cvRound(r_hist.at<float>(i-1)) ) ,
                      Point( bin_w*(i), hist_h - cvRound(r_hist.at<float>(i)) ),
                      Scalar( 0, 0, 255), 2, 8, 0  );
 }

 // Display

 imshow("calcHist Demo", histImage );
 imshow("The image resized",image);
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-08-29 09:27:29

再给这个问题加上一个答案。由于您使用的是OpenCV cv::Mat作为直方图持有者,因此将其扁平化的一种方法是使用reshape (例如:

代码语言:javascript
复制
// create mat a with 512x512 size and float type
cv::Mat a(512,512,CV_32F);
// resize it to have only 1 row
a = a.reshape(0,1);

这个O(1)函数不复制元素,只需将cv::Mat标头更改为具有正确的大小。

之后,您将有一个包含262144列的1行cv::mat。

票数 2
EN

Stack Overflow用户

发布于 2018-08-28 20:50:40

基本上,您想要扁平一个2D数组( hist = cv2.calcHist([image], [0, 1, 2], None, [bins, bins, bins], [5, 240, 5, 240, 5, 240])是2D数组235x3 )

这方面最简单的代码在function in C++ similar to numpy flatten

基本算法是( cf http://www.ce.jhu.edu/dalrymple/classes/602/Class12.pdf )。

代码语言:javascript
复制
for (q = 0; q < n; q++)
{
    for (t = 0; t < m; t++)
    {
        b[q * n + t] = a[q][t];  <-------
    }
}

来源:C++ 2D array to 1D array

(用于3D数组cf How to "flatten" or "index" 3D-array in 1D array? )

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52065142

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档