1

I do real-time traffic sign recognition using haar cascade. My webcam detects a sign then extracts frameROI, saves an image to a file and then I want to recognize this image using SVM,k-NN classifier etc(It's not done yet). But the problem is that sign is grabbed multiple times. How to solve this? I've done a research and I found a solution which is template matching. But how exactly should I use this function to stop taking frameROI of sign which was once detected? I'm a beginner so please be understanding.

Mat sign;

Dialog::Dialog(QWidget *parent) :QDialog(parent),ui(new Ui::Dialog)
{

    ui->setupUi(this);

    capWebcam.open(0);
    if (capWebcam.isOpened() == false) {
        QMessageBox::critical(this, tr("Błąd"), tr("brak kamerki"));
        return;
    }
    QTimer *timer = new QTimer;

    connect(timer, SIGNAL(timeout()), this, 
    SLOT(processFrameAndUpdateGUI()));
    timer->start(5);

}

void Dialog::processFrameAndUpdateGUI()
{
CascadeClassifier tsr_cascade;
tsr_cascade.load("a.xml");
Mat image;
Mat image2;
Mat frameROI;


capWebcam.read(image);
cvtColor(image, image2, CV_BGR2GRAY);
equalizeHist(image2, image2);
vector<Rect>znaki;

tsr_cascade.detectMultiScale(image2, znaki, 1.1, 3, CV_HAAR_FIND_BIGGEST_OBJECT | CV_HAAR_SCALE_IMAGE, Size(30, 30));


for (size_t i = 0; i < znaki.size(); i++)
{
    Point pt1(znaki[i].x + znaki[i].width, znaki[i].y + znaki[i].height);
    Point pt2(znaki[i].x, znaki[i].y);
    rectangle(image, pt1, pt2, cvScalar(0, 255, 0, 0), 1, 8, 0);
    frameROI = image(Rect(znaki[i].x, znaki[i].y, znaki[i].width, znaki[i].height));
    sign = frameROI;
}
imwrite("znak.jpg", sign);
QPixmap s = ("znak.jpg");

QImage qimg((uchar*)image.data, image.cols, image.rows, image.step, QImage::Format_RGB888);
QImage qimg2((uchar*)frameROI.data, frameROI.cols, frameROI.rows, frameROI.step, QImage::Format_RGB888);

ui->label_3->setPixmap(QPixmap::fromImage(qimg2));
ui->label->setPixmap(QPixmap::fromImage(qimg));
ui->label_2->setPixmap(s);
}

Dialog::~Dialog()
{
    delete ui;
}
yoGGie ツ
  • 21
  • 3

1 Answers1

2
connect(timer, SIGNAL(timeout()), this, SLOT(processFrameAndUpdateGUI()));
timer->start(5);

the function to grab the frame always timeout every 5 ms due to the signal timeout()

And timer is always running as per Timer::start()

Starts or restarts the timer with a timeout of duration msec milliseconds.

If the timer is already running, it will be stopped and restarted.

You need a single-shot timer.

// fires only once in 200 ms
QTimer::singleShot(200, this, SLOT(processFrameAndUpdateGUI()));
Joseph D.
  • 11,804
  • 3
  • 34
  • 67
  • How can singleshot timer help me? I have to refresh webcam's frame every 5ms cause it's real-time recognizing. – yoGGie ツ May 11 '18 at 15:35
  • @yoGGieツ, break your function. one that grabs the frame and will be triggered every 5ms and one triggered only once. as what the function name says, it's doing two things in one function. – Joseph D. May 12 '18 at 02:07