8 votes

Comment pousser une fenêtre de visualisation d'images OpenCV dans une interface graphique QT avec Visual studio ?

Je veux créer une interface graphique avec 2 rectangles pour visualiser les vidéos (un où l'on voit la vidéo d'entrée, un où l'on voit la vidéo post-traitée).

Je veux qu'il soit intégré à une interface graphique créée par QT, mais je veux que ces zones vidéo soient peuplées à partir d'OpenCV, comme une alternative à l'interface graphique d'OpenCV. cv::nameWindow méthode.

Comment puis-je le faire ?

11voto

borges Points 1565

Le flux de travail de base pour faire ce que vous désirez est :

  1. Ouvrir la vidéo avec l'API OpenCV (cvCreateFileCapture, par exemple)
  2. Récupérer les images IplImage de la vidéo (cvQueryFrame)
  3. Les convertir en QImage (voir le code joint ci-dessous)
  4. Afficher une QImage dans un QLabel (QLabel::setPixmap et QPixmap::fromImage)
  5. Mettre en boucle la mise à jour de la trame (en utilisant un QTimer, par exemple, avec le framerate vidéo)

Code pour convertir IplImage en QImage (en supposant des images RGB32Bits) :

QImage *IplImageToQImage(IplImage *input)
{
    if (!input)
        return 0;

    QImage image(input->width, input->height, QImage::Format_RGB32);

    uchar* pBits = image.bits();
    int nBytesPerLine = image.bytesPerLine();

    for (int n = 0; n < input->height; n++)
    {
        for (int m = 0; m < input->width; m++)
        {
            CvScalar s = cvGet2D(input, n, m);
            QRgb value = qRgb((uchar)s.val[2], (uchar)s.val[1], (uchar)s.val[0]);

            uchar* scanLine = pBits + n * nBytesPerLine;
            ((uint*)scanLine)[m] = value;
        }
    }

    return image;
}

La compréhension du code ci-dessus devrait être simple. Si vous avez des doutes, n'hésitez pas à nous en faire part.

Cette option de "bas niveau" vous permet de manipuler chaque image individuelle avant de l'afficher. Si vous souhaitez simplement afficher une vidéo via Qt, vous pouvez utiliser la fonction Cadre phonologique .

8voto

ypnos Points 21940

Voici le code qui convertit un cv::Mat en QImage. Les méthodes sont respectivement pour la virgule flottante 24bit RGB ou les niveaux de gris.

QImage Mat2QImage(const cv::Mat3b &src) {
        QImage dest(src.cols, src.rows, QImage::Format_ARGB32);
        for (int y = 0; y < src.rows; ++y) {
                const cv::Vec3b *srcrow = src[y];
                QRgb *destrow = (QRgb*)dest.scanLine(y);
                for (int x = 0; x < src.cols; ++x) {
                        destrow[x] = qRgba(srcrow[x][2], srcrow[x][1], srcrow[x][0], 255);
                }
        }
        return dest;
}

QImage Mat2QImage(const cv::Mat_<double> &src)
{
        double scale = 255.0;
        QImage dest(src.cols, src.rows, QImage::Format_ARGB32);
        for (int y = 0; y < src.rows; ++y) {
                const double *srcrow = src[y];
                QRgb *destrow = (QRgb*)dest.scanLine(y);
                for (int x = 0; x < src.cols; ++x) {
                        unsigned int color = srcrow[x] * scale;
                        destrow[x] = qRgba(color, color, color, 255);
                }
        }
        return dest;
}

Ensuite, vous pouvez utiliser la QImage dans un widget Qt. Voir la réponse de Borges.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X