在OpenCV中绘制Sobel算子幅度和角度的直方图
我想在OpenCV C++中绘制直方图。任务是x轴应该是角度,而y轴应该是直方图的大小。我使用Sobel算子计算幅度和角度。现在我怎样才能绘制直方图通过使用幅度和角度?在OpenCV中绘制Sobel算子幅度和角度的直方图
在此先感谢。问题的简单代码是
// Read image
Mat img = imread("abs.jpg");
img.convertTo(img, CV_32F, 1/255.0);
/*GaussianBlur(img, img, Size(3, 3), 0, 0, BORDER_CONSTANT);*/
// Calculate gradients gx, gy
Mat gx, gy;
Sobel(img, gx, CV_32F, 1, 0, 1);
Sobel(img, gy, CV_32F, 0, 1, 1);
// C++ Calculate gradient magnitude and direction (in degrees)
Mat mag, angle;
cartToPolar(gx, gy, mag, angle, 1);
imshow("magnitude of image is", mag);
imshow("angle of image is", angle);
好的,所以它的第一部分是计算它们每个的直方图。由于两者已经分开(在他们自己的Mat
中),我们不必分割它们或任何东西,我们可以直接在OpenCV的calcHist函数中使用它们。
通过的文件有:
void calcHist(const Mat* images, int nimages, const int* channels, InputArray mask, OutputArray hist, int dims, const int* histSize, const float** ranges, bool uniform=true, bool accumulate=false)
所以,你必须做的:
cv::Mat histMag, histAng;
// number of bins of the histogram, adjust to your liking
int histSize = 10;
// degrees goes from 0-360 if radians then change acordingly
float rangeAng[] = { 0, 360} ;
const float* histRangeAng = { rangeAng };
double minval, maxval;
// get the range for the magnitude
cv::minMaxLoc(mag, &minval, &maxval);
float rangeMag[] = { static_cast<float>(minval), static_cast<float>(maxval)} ;
const float* histRangeMag = { rangeMag };
cv::calcHist(&mag, 1, 0, cv::NoArray(), histMag, 1, &histSize, &histRangeMag, true, false);
cv::calcHist(&angle, 1, 0, cv::NoArray(), histAng, 1, &histSize, &histRangeAng, true, false);
现在,你必须绘制在histMag
和histAng
发现两个柱状图。
在我贴在你的情节线的评论turtorial,对角,将是这样的:
// Draw the histograms for B, G and R
int hist_w = 512; int hist_h = 400;
int bin_w = cvRound((double) hist_w/histSize);
cv::Mat histImage(hist_h, hist_w, CV_8UC3, Scalar(0,0,0));
/// Normalize the result to [ 0, histImage.rows ]
cv::normalize(histAng, histAng, 0, histImage.rows, cv::NORM_MINMAX, -1, Mat());
// Draw the lines
for(int i = 1; i < histSize; i++)
{
cv::line(histImage, cv::Point(bin_w*(i-1), hist_h - cvRound(histAng.at<float>(i-1))) ,
cv::Point(bin_w*(i), hist_h - cvRound(histAng.at<float>(i))),
cv::Scalar(255, 0, 0), 2, 8, 0 );
}
有了这个,你可以为大小做同样的,也可能转它变成了一个函数,如果它们被提供,它将绘制直方图。
在他们有另一种选择,绘制矩形的箱,使其适应我们的情况下的文档,我们得到这样的:
// Draw the histograms for B, G and R
int hist_w = 512; int hist_h = 400;
int bin_w = std::round(static_cast<double>(hist_w)/static_cast<double>(histSize));
cv::Mat histImage(hist_h, hist_w, CV_8UC3, Scalar(0,0,0));
/// Normalize the result to [ 0, histImage.rows ]
cv::normalize(histAng, histAng, 0, histImage.rows, cv::NORM_MINMAX, -1, Mat());
for(int i = 1; i < histSize; i++)
{
cv::rectangle(histImage, cv::Point(bin_w*(i-1), hist_h - static_cast<int>(std::round(histAng.at<float>(i-1)))), cv::Point(bin_w*(i), hist_h),);
}
同样,这可以用于幅度在要做的事同样的方式。这是超级简单的图,如果您需要更复杂或更美观的图,则可能需要调用外部库并将数据传递到计算出的直方图中。此外,这段代码还没有经过测试,所以它可能有错误或错误,但如果失败了,只需写一条评论,我们可以找到解决方案。
我希望这可以帮助你,并为迟到的答案抱歉。
非常感谢@ api55帮助我很多。但是绘制矩形的最后一段代码不能显示任何图形或点,请检查一下。他们只是向我展示矩形内没有任何点。 –
我的任务是x轴应该是角度,而y轴应该是直方图的大小?我怎么能得到这个? –
@GujjarAd是的,在一个柱状图中,你有一些箱子,它们有一堆计算点。要绘制幅度与直方图,它更容易,但我会建议不要使用OpenCV,但为此更好的库。尽管如此,使用'circle'绘图函数并绘制每个点的方法很简单。 – api55
您可以尝试[OpenCV教程](http://docs.opencv.org/2.4/doc/tutorials/imgproc/histograms/histogram_calculation/histogram_calculation.html),其中显示了如何计算和绘制直方图,您可以跳过分裂矩阵的步骤,因为你在这两种情况下有1个通道 – api55
@ api55问题是我不知道如何绘制幅度和角度,我可以将这些参数放在calHist函数中。请你给一点时间给代码。我只是在opencv非常初学者。谢谢。 –
因为我想要在X轴上的角度和在Y轴上的幅度,我怎样才能使用直方图来绘制它。请指导如果可能的话使用代码。谢谢 –