如何在Qt中比较两个RGB图像?

问题描述 投票:0回答:5

我需要比较两个彩色 RBG 图像并获得逐像素差异的结果图像。有什么想法我可以在 qt 中做到这一点吗?

如果您有任何帮助或建议,我将不胜感激。

c++ qt qt4 qt-creator
5个回答
4
投票

这是基于此 QtForum 问题的替代方案:

void substract(const QImage &left, const QImage &rigth, QImage &result)
{
  int w=min(left.width(), rigth.width());
  int h=min(left.height(),rigth.height();
  w=min(w, result.width());
  h=min(h, result.height();
  //<-This ensures that you work only at the intersection of images areas

  for(int i=0;i<h;i++){
    QRgb *rgbLeft=(QRgb*)left.constScanLine(i);
    QRgb *rgbRigth=(QRgb*)rigth.constScanLine(i);
    QRgb *rgbResult=(QRgb*)result.constScanLine(i);
    for(int j=0;j<w;j++){
        rgbResult[j] = rgbLeft[j]-rgbRigth[j];
    }
  }
}

0
投票

首先,RGB 图像是包含 3 个通道 (R,G,B) 的 3 维矩阵

要实现差异,您只需将矩阵相减即可。

如果您使用 OpenCv,请考虑下面的代码,否则您可以遍历矩阵并分别减去每个位置。

#include <cv.h>
#include <highgui.h>

using namespace cv;

Mat img = imread("...");
Mat img2 = imread("...");

Mat diff_img = img - img2;

0
投票

使用

QImage
,您可以在像素级别进行迭代,并简单地将 RBG 差异输出到第三个图像中。

QRgb QImage::pixel(int x, int y) const
void QImage::setPixelColor(int x, int y, const QColor &color)

请记住按顺序迭代行以获得最佳性能。这意味着该行应该是您的内部循环。很多时候,人们本能地做相反的事情,可能是因为大多数人优先考虑宽度而不是高度,因此将行作为外循环。


0
投票

这是比较两个相同尺寸(高度和宽度)图像的方法。您还可以使用一些 STD 功能来代替这个简单的代码。这只是为了展示它应该如何进行

// 'first' and 'second' it's  QImage objects 
int AbsoluteError = 0;
for (int y = 0; y < first.height(); ++y)
{
    QRgb *line1 = reinterpret_cast<QRgb*>(first.scanLine(y));
    QRgb *line2 = reinterpret_cast<QRgb*>(second.scanLine(y));
    for (int x = 0; x < first.width(); ++x)
    {
        QRgb &rgb1 = line1[x];
        int A1 = qAlpha(rgb1);
        int R1 = qRed(rgb1);
        int G1 = qGreen(rgb1);
        int B1 = qBlue(rgb1);

        QRgb &rgb2 = line2[x];
        int A2 = qAlpha(rgb2);
        int R2 = qRed(rgb2);
        int G2 = qGreen(rgb2);
        int B2 = qBlue(rgb2);

        bool A = A1 == A2;
        bool R = R1 == R2;
        bool G = G1 == G2;
        bool B = B1 == B2;

        if(!A || !R || !G || !B)
        {
            rgb2 = qRgba(qRed(rgb2), qGreen(0), qBlue(rgb2), qAlpha(rgb2));
            ++AbsoluteError;
        }
    }
}


ui->LineEdit1->setText(QString::number(AbsoluteError));
ui->LineEdit2->setText(QString::number((AbsoluteError*100)/(width1*height1))); //absolute error in %

-1
投票

bool ImagesAreSimilar(QImage *img1,QImage *img2) {

if (img1->isNull()||img2->isNull())
{
  return false ;
}
if (img1->height()!=img2->height()) {
    return false ;
}
if (img1->width()!=img2->width()) {
    return false ;
}
 auto pixel1 = img1->bits();
 auto pixel2 = img2->bits();
 bool similar=true;
for (int y = 0; y < img1->height(); y++)
{
    for (int x = 0; x < img1->width(); x++)
    {

        if (    (pixel1[0]!=pixel2[0])||
                (pixel1[1]!=pixel2[1])||
                (pixel1[2]!=pixel2[2])||
                (pixel1[3]!=pixel2[3])) {
                return false ;
        }
        pixel1  += 4;
        pixel2 += 4;
    }
}

返回相似;

}

© www.soinside.com 2019 - 2024. All rights reserved.