Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

matrod

reconhecimento de desenho.

Recommended Posts

Olá, sou novo no fórum, mas antes de mais nada não sou só mais um usuário desesperado por ajuda do tipo "PROVA AMANHÃ" hehehehe.

Apesar de ser, logo de cara, uma dúvida o meu primeiro post, com certeza continuarei usando este fórum para aumentar meu conhecimento e até mesmo ajudar outras pessoas um dia, quem sabe hehehe.

 

Bom agora vamos ao ponto, estou fazendo um programa(por iniciativa própria) de reconhecimento de desenho.

A funcionalidade do programa é o seguinte:

O usuário deve desenhar uma elipse, um retângulo e um triângulo num paintbox, e logo após soltar o mouse o programa deve corrigir essa forma para uma forma mais "precisa".

 

Vamos ao que eu consegui fazer até agora. (apenas um programa para desenhar)

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "CSPIN"
#pragma resource "*.dfm"
TForm1 *Form1;
int z, x1, x2, y1, y2;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
		: TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::RadioButton1Click(TObject *Sender)
{
PaintBox1->Canvas->Pen->Color = clBlack;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::RadioButton2Click(TObject *Sender)
{
PaintBox1->Canvas->Pen->Color = clBlue;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::RadioButton3Click(TObject *Sender)
{
PaintBox1->Canvas->Pen->Color = clRed;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
PaintBox1->Refresh();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::PaintBox1MouseDown(TObject *Sender,
	  TMouseButton Button, TShiftState Shift, int X, int Y)
{
z = 1;
PaintBox1->Canvas->MoveTo(X,Y);
PaintBox1->Canvas->Pixels[X][Y] = Color;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::PaintBox1MouseUp(TObject *Sender,
	  TMouseButton Button, TShiftState Shift, int X, int Y)
{
z = 0;
PaintBox1->Canvas->LineTo(X,Y);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::PaintBox1MouseMove(TObject *Sender,
	  TShiftState Shift, int X, int Y)
{
Edit1->Text = X;
Edit2->Text = Y;
if (z == 1)
PaintBox1->Canvas->LineTo(X,Y);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------

 

Estou usando a seguinte lógica, saber para qual forma corrigir usando as cores.

E para corrigir com as medidas aproximadas e no local exato(em cima da própria figura desenhada) pensei em encontrar e usar os pontos extremos (menor e maior X e Y).

 

Agora minha dúvida, estou começando em C++, e aprendendo pela internet com o que encontro. Não sei como faço para encontrar os pontos extremos.

Gostaria que alguém pudesse me ajudar com este passo, não o programa inteiro, quero continuar tendo trabalho após isso. =P

 

Agradeço a todos,

Matheus.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Pra quem está começando, é um programa um tanto difícil...

você vai ter que "simplificar" as retas de cada objeto.

 

por exemplo, imagine um quadrado no seguinte bitmap:

0 0 0 0 0 0 0 0 0 0
0 0 1 1 1 1 1 1 0 0
0 0 1 0 0 0 0 1 0 0
0 0 1 0 0 0 0 1 0 0
0 0 1 0 0 0 0 1 0 0
0 0 1 0 0 0 0 1 0 0
0 0 1 0 0 0 0 1 0 0
0 0 1 1 1 1 1 1 0 0
0 0 0 0 0 0 0 0 0 0

Como você faz o programa saber que é um quadrado?

você pega um ponto do desenho e veja se faz parte de uma linha reta.

por exemplo:

(o ponto aleatório escolhido é marcado pos um 'x', esse ponto deve ser um pixel PINTADO, ou seja, 1)

0 0 0
1 x 1   -> linha reta!
0 0 0

0 1 0
0 x 0  -> linha reta!
0 1 0

0 0 1
0 x 0 -> linha reta, mas não existe uma linha desse tipo num quadrado
1 0 0

você encontra as extremidades quando:

0 0 0
0 x 1  -> canto superior esquerdo
0 1 0

0 1 0
1 x 0 -> canto inferior direito
0 0 0

etc...

Não sei c eu consegui te passar a idéia, qualquer coisa posta ai!

=D

 

http://forum.imasters.com.br/public/style_emoticons/default/thumbsup.gif

Compartilhar este post


Link para o post
Compartilhar em outros sites

Opa, peguei a idéia sim, mas por exemplo, o desenho do usuário sairá bastante tremido, e pode ser que o X máximo esteja no meio da figura, como um retângulo do tipo:

 

 

0 0 0 0 0 0 0
0 1 1 1 1 1 0
0 1 0 0 0 1 0
0 1 0 0 0 0 1 (aqui)
0 1 0 0 0 1 0
0 1 0 0 0 1 0
0 1 1 1 1 1 0

tem como anular este pixel?

ou a correção passaria com uma abscissa pelo ponto X máximo e o retângulo corrigido ficaria maior que o desenhado?

sobre "simplificar" como você disse, imagino que seja isto que quis dizer, mas, não tenho a menor idéia de como fazer isso. (sou um tanto ignorante ainda pra pensar como programador =P)

 

 

EDIT: E opa, claro, fui tão empolgado por estar avançando nesse programa que nem agradeci hehehe.

Obrigado pela ajuda!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Que bom que você pegou a idéia inicial.

Todo e qualquer tratamento de imagens parte dos mesmos princípios.

 

quando eu disse em simplificar a imagem, eu disse pra você criar um bitmap de 2 bits.

Pixeis brancos serão 0's (zeros) e pixeis pintados serão 1's (uns)

Assim ficará MUITO mais fácil do que trabalhar com a paleta RGB, não é? hahahahaha

 

você tem que determinar uma margem de erro, pois como você mesmo disse, o desenho do usuário são será perfeitinho, e a sua matriz será razoavelmente grande.

Por exemplo, vamos supor que a sua margem de erro seja 3 pixeis (em X e em Y)

1 1 0 0 0
1 1 0 0 0
0 1 1 0 0  -> isso aqui ainda é uma linha reta para o seu programa.
0 0 1 1 0
0 1 1 0 0

0 1 0 0 0
0 1 1 0 0
1 1 0 0 0  
0 0 0 1 1  -> isso aqui não: note o último bit dessa mesma linha, 
1 1 0 0 0	   ele está mais de 3 pixeis deslocado do ultimo pixel da linha anterior
0 1 1 0 0

Cara, eu nunca fiz nada parecido com isso que você está fazendo. Essa é a forma que eu tentaria uma primeira abordagem.

Ou então você pode esquecer as linhas retas, e buscar apenas os cantos do quadrado.

// canto[0] = posição em X		canto[1] = posição em Y
canto1[2]
canto2[2]
canto3[2]
canto4[2]

	  1 --------------- 2
	  |				   |
	  |				   |
	  |				   |
	  |				   |
	  3 ---------------- 4

faça uma média das medididas, por exemplo, para desenhar a reta superior do quadrado corrigido:

ela começa em:

Y:

abs (canto1[1] - canto2[1]) + menor(canto1[1], canto2[1]);

X:

a mesma média anterior, mas dessa vez com o canto1 e 3

 

e acaba em:

Y:

igual

X:

a mesma "média" mas com o canto2 e 4

 

 

ps.: abs() é o valor absoluto, por exemplo: abs( - 4 ) = 4

Compartilhar este post


Link para o post
Compartilhar em outros sites

Certo, entendi!

Bom, então fazendo por variações X e Y não vou mais precisar das cores para identificar os formatos.

 

Vou repensar agora o programa, e se forem sugindo dúvidas vou postando neste tópico.

 

Muito obrigado pela ajuda. Esse está sendo o programa mais difícil que fiz até agora. =P

Compartilhar este post


Link para o post
Compartilhar em outros sites

Quando terminar, poste la no laboratório de códigos fontes!

Quero ver isso funcionando! =D

http://forum.imasters.com.br/public/style_emoticons/default/thumbsup.gif

 

Detalhe, seja bem vindo ao fórum!

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.