PDA

View Full Version : Painting in multiple QWidgets simultaneously



edepetete
17th October 2011, 17:21
Hi folks,

I'm currently writing a Qt Application, which is based on RGBDemo by Nicolas Burros. It makes use of Microsoft's Kinect Camera. Here the QWidget is adapted in such way that it can display Images passed to it by OpenCV (imageWidget). So here's my question...

I have figured out how do paint dots in this costumized widget (overwriting the paintEvent method) and I can draw dots in both images. Now I want a dot that is drawn in the left image to be drawn in the right image also (see attached picture)

6989


/**
* This file is part of the nestk library.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Author: Nicolas Burrus <nicolas.burrus@uc3m.es>, (C) 2010
*/

#include "image_widget.h"

#include <ntk/ntk.h>

#include <QMouseEvent>
#include <QPainter>

using namespace cv;

namespace ntk
{
ImageWidget :: ImageWidget(QWidget* parent){
clicks = 1;
}


void ImageWidget :: mouseMoveEvent ( QMouseEvent * event )
{
if (m_image.isNull())
{
event->ignore();
return;
}

int x = event->x() * (m_image.width() / float(width()));
int y = event->y() * (m_image.height() / float(height()));
m_last_mouse_pos = QPoint(x,y);
emit mouseMoved(x,y);
}

void ImageWidget :: mousePressEvent ( QMouseEvent * event )
{
int x = event->x() * (m_image.width() / float(width()));
int y = event->y() * (m_image.height() / float(height()));
m_last_mouse_pos = QPoint(x,y);


}

void ImageWidget :: mouseReleaseEvent ( QMouseEvent * event )
{
int x = event->x() * (m_image.width() / float(width()));
int y = event->y() * (m_image.height() / float(height()));
if ((QPoint(x,y) == m_last_mouse_pos && event->button() == Qt::LeftButton))
{

if (clicks % 3 == 1){
fstMouseClick = event->pos();
}

if (clicks % 3 == 2){
sndMouseClick = event->pos();
}

if (clicks % 3 == 0){
thdMouseClick = event->pos();
}
clicks++;
emit mouseClicked(x,y);
}
}


void ImageWidget :: setImage(const QImage& im)
{
m_image = im;
update();
}

void ImageWidget :: setRects(const std::list<cv::Rect>& rects, const cv::Vec3b& color)
{
m_rects = rects;
m_rect_color = color;
update();
}

void ImageWidget :: setTexts(const std::vector<TextData> texts)
{
m_texts = texts;
update();
}

void ImageWidget :: setImage(const cv::Mat1b& im)
{
if (m_image.width() != im.cols
|| m_image.height() != im.rows)
m_image = QImage(im.cols, im.rows, QImage::Format_RGB32);

for (int r = 0; r < im.rows; ++r)
{
QRgb* ptr = (QRgb*) m_image.scanLine(r);
for (int c = 0; c < im.cols; ++c)
{
int v = im(r,c);
*ptr = qRgb(v,v,v);
++ptr;
}
}
update();
}

void ImageWidget :: setImage(const cv::Mat1f& im, double* i_min_val, double* i_max_val)
{
if (m_image.width() != im.cols
|| m_image.height() != im.rows)
m_image = QImage(im.cols, im.rows, QImage::Format_RGB32);

double min_val, max_val;
if (i_min_val && i_max_val)
{
min_val = *i_min_val;
max_val = *i_max_val;
}
else
minMaxLoc(im, &min_val, &max_val);
if (min_val == max_val)
{
m_image.fill(qRgb(0,0,0));
return;
}

for (int r = 0; r < im.rows; ++r)
{
QRgb* ptr = (QRgb*) m_image.scanLine(r);
const float* cv_ptr = im.ptr<float>(r);
for (int c = 0; c < im.cols; ++c)
{
int v = 255*(*cv_ptr-min_val)/(max_val-min_val);
v = ntk::saturate_to_range(v, 0, 255);
int rgb = (0xff << 24) + (v << 16) + (v << 8) + v;
*ptr = rgb;
++ptr;
++cv_ptr;
}
}
update();
}

void ImageWidget :: setImage(const cv::Mat3b& im)
{
if (m_image.width() != im.cols
|| m_image.height() != im.rows)
m_image = QImage(im.cols, im.rows, QImage::Format_RGB32);

for (int r = 0; r < im.rows; ++r)
{
QRgb* ptr = (QRgb*) m_image.scanLine(r);
const uchar* cv_ptr = im.ptr(r);
for (int i = 0; i < im.cols; ++i)
{
int rgb = 0xff << 24;
rgb |= (*cv_ptr++);
rgb |= ((*cv_ptr++) << 8);
rgb |= ((*cv_ptr++) << 16);
*ptr++ = rgb;
}
}
update();
}

double ImageWidget :: scaleX() const
{
return double(rect().width())/m_image.rect().width();
}

double ImageWidget :: scaleY() const
{
return double(rect().height())/m_image.rect().height();
}

void ImageWidget :: setPen(QPen pen)
{
m_pen = pen;
}


void ImageWidget :: paintEvent(QPaintEvent * event)
{
double sx = scaleX();
double sy = scaleY();

if (m_pen.data_ptr() == NULL){
QPen p;
m_pen = p;
m_pen.setColor(Qt::white);
m_pen.setWidth(2);
}

QPainter painter(this);
painter.drawImage(rect(), m_image, m_image.rect());

if (clicks % 3 == 2){
painter.setPen(Qt::red);
painter.setBrush(Qt::red);
painter.drawEllipse(fstMouseClick.x()-2,fstMouseClick.y()-2,4,4);
}

if (clicks % 3 == 0){
painter.setPen(Qt::red);
painter.setBrush(Qt::red);
painter.drawEllipse(fstMouseClick.x()-2,fstMouseClick.y()-2,4,4);
painter.drawEllipse(sndMouseClick.x()-2,sndMouseClick.y()-2,4,4);
}

if (clicks % 3 == 1 && clicks != 1){
painter.setPen(Qt::red);
painter.setBrush(Qt::red);
painter.drawEllipse(fstMouseClick.x()-2,fstMouseClick.y()-2,4,4);
painter.drawEllipse(sndMouseClick.x()-2,sndMouseClick.y()-2,4,4);
painter.drawEllipse(thdMouseClick.x()-2,thdMouseClick.y()-2,4,4);
}

m_pen.setColor(qRgb(m_rect_color[0], m_rect_color[1], m_rect_color[2]));
painter.setPen(m_pen);
foreach_const_it(it, m_rects, std::list<cv::Rect>)
{
const cv::Rect& r = *it;
QRect qr (r.x*sx, r.y*sy, r.width*sx, r.height*sy);
painter.drawRect(qr);
}

foreach_idx(i, m_texts)
{
const cv::Vec3b& c = m_texts[i].color;
m_pen.setColor(qRgb(c[0], c[1], c[2]));
painter.setFont(QFont("Helvetica", 14));
painter.setPen(m_pen);
QString s (m_texts[i].text.c_str());
QPoint p (m_texts[i].x*sx, m_texts[i].y*sy);
painter.drawText(p, s);
}
}
} // ntk

This is the code of mentioned imageWidget. Please note that most code in the paintEvent is used for drawing the Kinect Image. Only the part with the "clicks"-variable is relevant for the dots.

Do you guys have any hint for me how this can be done?

BTW both images are the same size

Cheers
edepetete