我按照这个示例用 Qt 绘制了一个 RGB 直方图。我有三个不同的 QBarSet,每个颜色通道一个。
我现在的问题是所有的条都彼此相邻绘制。是否有可能在彼此前面绘制条形图?
这就是我想要的: 链接
由于在我的示例中条形图都是彼此相邻绘制的,因此它们太窄了。
我用 QStackedBarSeries 和一些手工计算解决了我的问题。
我的代码:
// Histogramms
std::vector<int> nGrayValues(NOGRAYLEVELS, 0);
std::vector<int> nRedValues(NOGRAYLEVELS, 0);
std::vector<int> nGreenValues(NOGRAYLEVELS, 0);
std::vector<int> nBlueValues(NOGRAYLEVELS, 0);
QRgb* imPixels= reinterpret_cast< QRgb* >(image.bits());
for (quint64 i = 0; i < numberPixels; i++) {
nGrayValues[static_cast<unsigned int>(qGray(imPixels[i]))]++;
nRedValues[static_cast<unsigned int>(qRed(imPixels[i]))]++;
nGreenValues[static_cast<unsigned int>(qGreen(imPixels[i]))]++;
nBlueValues[static_cast<unsigned int>(qBlue(imPixels[i]))]++;
}
QStackedBarSeries* pSeries = new QStackedBarSeries();
QBarSet* grayBarSet = new QBarSet("Gray");
grayBarSet->setColor(Qt::black);
QBarSet* redBarSet = new QBarSet("Red");
redBarSet->setColor(Qt::red);
QBarSet* greenBarSet = new QBarSet("Green");
greenBarSet->setColor(Qt::green);
QBarSet* blueBarSet = new QBarSet("Blue");
blueBarSet->setColor(Qt::blue);
double totalMaxValue = 0.0;
if (numberPixels != 0) {
double numberPixels_f = static_cast<double>(numberPixels);
for (unsigned int i = 0; i < NOGRAYLEVELS; i++) {
// Helper function
auto calcPart = [=](int value, int& maxValue) -> int
{
int temp = value - maxValue;
if (temp > 0) {
maxValue = value;
return temp;
} else {
return 0;
}
};
int grayPart = 0, redPart = 0, greenPart = 0, bluePart = 0, maxPart = 0;
grayPart = calcPart(nGrayValues[i], maxPart);
redPart = calcPart(nRedValues[i], maxPart);
greenPart = calcPart(nGreenValues[i], maxPart);
bluePart = calcPart(nBlueValues[i], maxPart);
// normalize histogramm entries as procent
*grayBarSet << grayPart * 100.0 / numberPixels_f;
*redBarSet << redPart * 100.0 / numberPixels_f;
*greenBarSet << greenPart * 100.0 / numberPixels_f;
*blueBarSet << bluePart * 100.0 / numberPixels_f;
double m1 = std::max(gray, red);
double m2 = std::max(green, blue);
double maxValue = std::max(m1, m2);
if (maxValue > totalMaxValue) {
totalMaxValue = maxValue;
}
}
}
pSeries->append(grayBarSet);
pSeries->append(redBarSet);
pSeries->append(greenBarSet);
pSeries->append(blueBarSet);
// add series to the chart and update axisY
pChart->removeAllSeries();
axisY->setRange(0, totalMaxValue);
pChart->addSeries(pSeries);
各个颜色以固定顺序绘制(灰色 -> 红色 -> 绿色 -> 蓝色)。