[英]How to turn an array of data of a cropped image in openCV into a RGB Histogram in Qt
我有一个由两个QGraphicsView组成的界面:一个QGraphicsView用于显示来自右摄像机的图像,第二个QGraphicsView用于显示来自左摄像机的图像。 两个QGraphicsViews也都用于上传图像(例如,从文件中上传),以便可以执行图像处理操作。 例如,一旦图像上传到左边,我就可以在图像的特定特征上画一个框并将其提取出来。 右键单击鼠标后,我将打开一个菜单。 我正在努力的功能之一是,我试图将从绘制的框派生的裁剪图像转换为RGB直方图。 我正在使用openCV将图像转换为一系列数组,并将这些数组传递给3个QLabel以显示R,G,B直方图。 但是,我无法绘制RGB直方图,也无法抓住错误。 我将附加UI快照以获取信息:
该代码也附在下面:
clipscene.h
#ifndef CLIPSCENE_H
#define CLIPSCENE_H
#include <QDialog>
#include <QGraphicsScene>
#include <QGraphicsPixmapItem>
#include "opencv2/imgproc.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/highgui/highgui.hpp"
namespace Ui {
class clipScene;
}
class clipScene : public QDialog
{
Q_OBJECT
public:
explicit clipScene(QWidget *parent = 0);
~clipScene();
void setImage(QImage img);
void setBoundingBox(QRect rect);
private slots:
void on_closeBtn_clicked();
void on_acceptBtn_clicked();
void showEvent(QShowEvent *);
private:
Ui::clipScene *ui;
QImage simg, simgR, simgG, simgB;
QRect srect;
QGraphicsScene *scene;
};
#endif // CLIPSCENE_H
和clipscene.cpp
#include "clipscene.h"
#include "ui_clipscene.h"
using namespace cv;
clipScene::clipScene(QWidget *parent) :
QDialog(parent),
ui(new Ui::clipScene)
{
ui->setupUi(this);
scene = new QGraphicsScene();
ui->graphicsViewClipped->setScene(scene);
ui->redImg->setText("<b>Calculate Graph</b>");
ui->greenImg->setText("<b>Calculate Graph</b>");
ui->blueImg->setText("<b>Calculate Graph</b>");
}
clipScene::~clipScene()
{
delete ui;
}
void clipScene::setImage(QImage img)
{
simg = img;
QGraphicsPixmapItem* item = new QGraphicsPixmapItem(QPixmap::fromImage(simg));
scene->addItem(item);
ui->graphicsViewClipped->show();
cv::Mat input = cv::Mat(simg.height(), simg.width(), QImage::Format_ARGB32, simg.bits(), simg.bytesPerLine());
cv::Mat channel[3];
// Establish the number of bins
int hbins = 30, sbins = 32;
int histSize[] = {hbins, sbins};
// Set the ranges ( for B,G,R) )
float hranges[] = { 0, 180 };
// saturation varies from 0 (black-gray-white) to 255 (pure spectrum color)
float sranges[] = { 0, 256 };
const float* histRange[] = { hranges, sranges };
bool uniform = true; bool accumulate = false;
split(input, channel);
int channels[] = {0, 1}; // Now for one channel (R)
MatND hist;
cv::calcHist(&input, 1, channels, Mat(), hist, 1, histSize, histRange, uniform, accumulate);
// The actual splitting.
double maxVal=0;
minMaxLoc(hist, 0, &maxVal, 0, 0);
int scale = 10;
Mat histImg = Mat::zeros(sbins*scale, hbins*10, CV_8UC3);
for( int h = 0; h < hbins; h++ )
for( int s = 0; s < sbins; s++ )
{
float binVal = hist.at<float>(h, s);
int intensity = cvRound(binVal*255/maxVal);
// The arrays of data in openCV should be used here to draw
// the histogram
}
ui->redImg->setScaledContents(true);
ui->redImg->setPixmap(QPixmap::fromImage(QImage(channel[0].data, channel[0].cols, channel[0].rows, channel[0].step, QImage::Format_ARGB32) \
.scaled(200,200,Qt::KeepAspectRatio,Qt::SmoothTransformation)));
}
我发现了这一点,并且还在阅读openCV文档中的其他资料,但问题仍然存在。 关于如何解决此问题的任何想法?
使用OpenCV的此示例 ,同样为了显示图形,请使用QChartView
,如下所示:
#include <QApplication>
#include <QtCharts>
QT_CHARTS_USE_NAMESPACE
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
static cv::Mat QImageToMat(const QImage & image){
cv::Mat out;
switch(image.format()) {
case QImage::Format_Invalid:
{
cv::Mat empty;
empty.copyTo(out);
break;
}
case QImage::Format_RGB32:
{
cv::Mat view(image.height(),image.width(),CV_8UC4,(void *)image.constBits(),image.bytesPerLine());
view.copyTo(out);
break;
}
case QImage::Format_RGB888:
{
cv::Mat view(image.height(),image.width(),CV_8UC3,(void *)image.constBits(),image.bytesPerLine());
cv::cvtColor(view, out, cv::COLOR_RGB2BGR);
break;
}
default:
{
QImage conv = image.convertToFormat(QImage::Format_ARGB32);
cv::Mat view(conv.height(),conv.width(),CV_8UC4,(void *)conv.constBits(),conv.bytesPerLine());
view.copyTo(out);
break;
}
}
return out;
}
static std::vector<cv::Mat> calculate_histogram(const QImage & image){
cv::Mat src = QImageToMat(image);
std::vector<cv::Mat> bgr_planes;
cv::split(src, bgr_planes );
/// Establish the number of bins
int histSize = 256;
/// Set the ranges ( for B,G,R) )
float range[] = { 0, 256 } ;
const float* histRange = { range };
bool uniform = true; bool accumulate = false;
std::vector<cv::Mat> hist;
for(std::size_t i = 0; i < bgr_planes.size(); ++i){
hist.push_back(cv::Mat());
cv::calcHist( &bgr_planes[i], 1, 0, cv::Mat(), hist[i], 1, &histSize, &histRange, uniform, accumulate );
}
return hist;
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QImage image(":/lena.png");
QChartView *view = new QChartView;
QChart *chart = new QChart;
view->setChart(chart);
const QStringList titles{"Blue", "Green", "Red"};
std::vector<cv::Mat> hist_planes = calculate_histogram(image);
for(std::size_t i = 0; i< 3; ++i){
const cv::Mat mat = hist_planes[i];
QLineSeries *series = new QLineSeries;
series->setColor(QColor(titles[i]));
series->setName(titles[i]);
for(int j=0; j < mat.rows; ++j){
*series << QPoint(j, mat.at<float>(j));
}
chart->addSeries(series);
}
chart->createDefaultAxes();
chart->axisX()->setGridLineVisible(false);
chart->axisY()->setGridLineVisible(false);
QLabel *label = new QLabel;
label->setPixmap(QPixmap::fromImage(image));
QWidget w;
QHBoxLayout *lay = new QHBoxLayout(&w);
lay->addWidget(label);
lay->addWidget(view);
w.show();
return a.exec();
}
在下面的链接中,您可以找到完整的示例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.