繁体   English   中英

如何在openCV中将裁剪图像的数据数组转换为Qt中的RGB直方图

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM