Я хочу держать заполненный прямоугольник в окне, но не удалось. Пожалуйста, скажи мне почему. - PullRequest
0 голосов
/ 12 марта 2012

Код может быть собран и работает, но он не работает так, как я хочу.Я хочу использовать мышь, чтобы нарисовать прямоугольник в окне.Когда кнопка нажата, она начинает рисовать.Когда кнопка отпущена, последний прямоугольник должен быть заполнен и сохранен в окне.

Я внимательно изучил код и действительно не знаю, почему он не работает таким образом.Пожалуйста, скажите мне. PS: мне удалось реализовать функциональность с помощью небольшой модификации.Я просто хочу знать, в чем проблема в этой программе.

#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
#include <iostream>

using namespace std;

CvRect rect;
bool g_press = false;

void my_mouse_callback(int event, int x, int y, int flags, void* param);

int main(){
 IplImage *img = cvCreateImage(cvSize(500, 500), 8, 3);
 cvZero(img);
 cvAddS(img, cvScalarAll(255), img);
 IplImage *temp = cvCloneImage(img);
 cvNamedWindow("FUN");
 cvSetMouseCallback("FUN", my_mouse_callback, (void*) temp);
 cout<<1<<endl;

//if the mouse is pressed, use the statement in while to draw. If the mouse is released, use the callback to draw.
//
 while(1){
 if(g_press) {
 temp = cvCloneImage(img);
 cvRectangle(temp, cvPoint(rect.x, rect.y), cvPoint(rect.x+rect.width, rect.y+rect.height), CV_RGB(50,50,50));
 }
 cvShowImage("FUN", temp);
 if(cvWaitKey(15) == 27) break;
 }
 cvReleaseImage(&img);
 cvDestroyWindow("FUN");
}

//callback function for mouse

void my_mouse_callback(int event, int x, int y, int flags, void* param){
 IplImage* img = (IplImage*) param;
 switch(event){
 case CV_EVENT_MOUSEMOVE:
 {
 if(g_press == true){
 rect.width = x - rect.x;
 rect.height = y - rect.y;
 }
 }break;
 case CV_EVENT_LBUTTONDOWN:
 {
 g_press = true;
 rect.x = x;
 rect.y = y;
 rect.height = rect.width = 0;
 }break;
 case CV_EVENT_LBUTTONUP:
 {
 g_press = false;
 if(rect.width < 0){
 rect.x += rect.width;
 rect.width *= -1;
 }
 if(rect.height <0){
 rect.y += rect.height;
 rect.height *= -1;
 }

////By this statement, I want to fill the final rectangle and hold it in the window. I examined it for several times and I did not find mistakes. I just want to know the reason.
 cvRectangle(img, cvPoint(rect.x, rect.y), cvPoint(rect.x+rect.width, rect.y+rect.height), CV_RGB(50,50,50), CV_FILLED);
 }break;
 }
}

1 Ответ

1 голос
/ 12 марта 2012

Вот что я наблюдал в Mac OS X: после рисования прямоугольника он остается видимым, пока я снова не щелкну мышью внутри окна. Причина этого:

if(g_press) {
    temp = cvCloneImage(img);
    cvRectangle(temp, cvPoint(rect.x, rect.y), cvPoint(rect.x+rect.width, rect.y+rect.height), CV_RGB(50,50,50));
 }

каждый раз, когда происходит щелчок, вы клонируете исходное изображение (чистое / пустое), и это приводит к потере прямоугольника, который был нарисован.

Если это то, что вы ожидали, это работает в моей системе.

EDIT:

Я выполнил более полный анализ вашего кода, и проблема довольно очевидна: все, что вы делаете внутри my_mouse_callback(), отменяется из-за if, о котором я упоминал ранее.

Если вы обратите пристальное внимание, вы заметите, что выполнение вашего приложения происходит следующим образом: my_mouse_callback() вызывается, когда приходит событие мыши, затем оно меняет значение g_press, конфигурирует структуру rect с правильные параметры и, наконец, рисует прямоугольник на изображении.

Сразу после этого срабатывает условие if внутри while и temp = cvCloneImage(img); перезаписывает чертеж, созданный с помощью обратного вызова: OOPSIE! А затем вы рисуете другой прямоугольник, который не установлен как CV_FILLED. Другими словами, прямоугольник, который вы видите на окне, вызван:

if(g_press) {
    temp = cvCloneImage(img);
    cvRectangle(temp, cvPoint(rect.x, rect.y), cvPoint(rect.x+rect.width, rect.y+rect.height), CV_RGB(50,50,50));
}

а не по обратному вызову! Итак, чтобы подвести итог очевидности, если вы хотите, чтобы прямоугольник был заполнен, просто измените этот последний вызов на:

cvRectangle(temp, cvPoint(rect.x, rect.y), cvPoint(rect.x+rect.width, rect.y+rect.height), CV_RGB(50,50,50), CV_FILLED);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...