我正在使用下一个算法来计算YUV420sp图像的直方图。似乎工作,但对于完全黑暗的图像,结果不是100%准确。当图像较暗时,我希望在直方图的左侧有一个高选择,显示图像太暗,但这种情况下的算法显示的是平线,没有选择。在其他光线情况下,直方图似乎是准确的。
void calculateHistogram(const unsigned char* yuv420sp, const int yuvWidth, const int yuvHeight, const int histogramControlHeight, int* outHistogramData)
{
const int BINS = 256;
// Clear the output
memset(outHistogramData, 0, BINS * sizeof(int));
// Get YUV brightness values
const int totalPixels = yuvWidth * yuvHeight;
for (int index = 0; index < totalPixels; index++)
{
char brightness = yuv420sp[index];
outHistogramData[brightness]++;
}
// Get the maximum brightness
int maxBrightness = 0;
for (int index = 0; index < BINS; index++)
{
if (outHistogramData[index] > maxBrightness)
{
maxBrightness = outHistogramData[index];
}
}
// Normalize to fit the UI control height
const int maxNormalized = BINS * histogramControlHeight / maxBrightness;
for(int index = 0; index < BINS; index++)
{
outHistogramData[index] = (outHistogramData[index] * maxNormalized) >> 8;
}
}
[由galop1n解决]虽然Galop1n实现更好,但我正在更新这个更正,以防万一对任何人都有用。
的变化:
1)将亮度值读入unsigned char而不是char。
2)将UI规范化划分放入规范化循环。
void calculateHistogram(const unsigned char* yuv420sp, const int yuvWidth, const int yuvHeight, const int histogramCanvasHeight, int* outHistogramData)
{
const int BINS = 256;
// Clear the output
memset(outHistogramData, 0, BINS * sizeof(int));
// Get YUV brightness values
const int totalPixels = yuvWidth * yuvHeight;
for (int index = 0; index < totalPixels; index++)
{
unsigned char brightness = yuv420sp[index];
outHistogramData[brightness]++;
}
// Get the maximum brightness
int maxBrightness = 0;
for (int index = 0; index < BINS; index++)
{
if (outHistogramData[index] > maxBrightness)
{
maxBrightness = outHistogramData[index];
}
}
// Normalize to fit the UI control height
for(int index = 0; index < BINS; index++)
{
outHistogramData[index] = outHistogramData[index] * histogramCanvasHeight / maxBrightness;
}
}
答案 0 :(得分:1)
您的实施中至少存在两个错误。
我还建议使用std::array
(需要c ++ 11)来存储结果而不是原始指针,因为调用者没有为使用该函数的内容分配足够的空间。< / p>
#include <algorithm>
#include <array>
void calculateHistogram(const unsigned char* yuv420sp, const int yuvWidth, const int yuvHeight, const int histogramControlHeight, std::array<int, 256> &outHistogramData ) {
outHistogramData.fill(0);
std::for_each( yuv420sp, yuv420sp + yuvWidth * yuvHeight, [&](int e) {
outHistogramData[e]++;
} );
int maxCountInBins = * std::max_element( begin(outHistogramData), end(outHistogramData) );
for( int &bin : outHistogramData )
bin = bin * histogramControlHeight / maxCountInBins;
}
答案 1 :(得分:0)
如果图像maxBrightness
的最大亮度为零,则maxNormalized的计算将除以零。我怀疑这是你的问题所在。
如果没有更好地了解您正在尝试建立的规范化条件,我不确定您现在可以选择哪种替代方案。