嗨,我在python中编写了以下代码行:
# 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 ++重写它。我在http://www.swarthmore.edu/NatSci/mzucker1/opencv-2.4.10-docs/doc/tutorials/imgproc/histograms/histogram_calculation/histogram_calculation.html
找到了一个很好的例子我现在面临的问题是将c ++中的hist扁平化,例如python代码。这就是python(512,)中的hist扁平化输出的形状。有什么想法可以在c ++中获得相同的结果吗?
(编辑) 到目前为止的c ++代码。
大小大小(500,500); 图片= imread(“ C:\ johan.jpg”,IMREAD_COLOR);
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);
答案 0 :(得分:1)
基本上,您想展平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)
for (q = 0; q < n; q++)
{
for (t = 0; t < m; t++)
{
b[q * n + t] = a[q][t]; <-------
}
}
(对于3D阵列cf How to "flatten" or "index" 3D-array in 1D array?)
答案 1 :(得分:1)
只需为这个问题再添加一个答案即可。由于您将OpenCV cv :: Mat用作直方图持有者,因此将其展平的一种方法是使用重塑,例如:
// 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标头更改为具有正确的大小。
之后,您将获得1行cv :: mat和262144列。