View Full Version : [C++] Individuare pallino rosso
Ciao a tutti oggi ho da proporvi 1 progetto che non so se sia realizzabile... Quello che vorei fare io sarebbe creare un programma che riesca ad individuare un pallino rosso sempre della stessa dimensione, colore e forma all' interno di una pagina web o di una immagine a seconda di quale delle due è più semplice da realizzare e a restituirne la posizione.
Il problema è che non so proprio da dove partire, non è cqualcuno conosce qualche funzione che mi potrebbe essere utile?
grazie i anticipo.
usando un'immagine puoi semplicemente fare una scansione per regione/per pixel.
Diciamo che il pallino rosso è iscritto in un quadrato di 10 pixel di lato. Il gioco è già fatto. Fai un bel ciclo sui pixel dell'immagine prendendo ogni volta una regione quadrata di 10 pixel di lato. Se la distribuzione dei pixel rossi all'interno del quadrato estratto dall'immagini è la stessa del quadrato in cui è iscritto il cerchio da rilevare allora hai trovato quello che cercavi.
Questo nel presupposto elementare che il cerchio da el'immagine corrisponda esattamente a quello da da trovare.
Requisito che potrebbe essere poco probabile, soprattutto se la ricerca avvegna sullo screenshot di una pagina web. In questo caso non coincideranno nè le dimensioni nè i colori.
mi dareste qualche dritta giusto per iniziare?
Pallino rosso in un'immagine bitmap.
Iniziamo a ridurre il problema ad un insieme di problemi più piccoli.
Definiamo Pallino come un oggetto che è in grado di dire se una matrice
quadrata di lato N pixel rappresenti o no un cerchio rosso iscritto in una
matrice di uguali dimensioni.
class Pallino
+èUnCerchio(p : MatriceQuadrataDiPixel) : boolean
Dove una MatriceQuadrataDiPixel è:
class MatriceQuadrataDiPixel
+size() : int
+getPixel(riga : int, colonna : int) : Pixel
E un Pixel è, supponiamo, una tripletta rosso-verde-blu:
class Pixel
+rosso() : int
+verde() : int
+blu() : int
Ci serve anche qualcosa che data una bitmap sia in grado di trasformarla in un set di
matrici di pixel di lato N.
class GeneratoreDiMatrici
+GeneratoreDiMatrici(b : ImmagineBitmap, n : pixelPerLato)
+estraiMatrici() : ListaDiMatriciQuadrateDiPixel
Dove ListaDiMatriciQuadrateDiPixel è... una lista:
class ListaDiMatriciQuadrateDiPixel
+size() : int
+get(indice : int) : MatriceQuadrataDiPixel
Ora basta applicare un pallino al prodotto del generatore di matrici per avere
la risposta cercata.
class Applicatore
+esisteUnCerchioRosso(p : Pallino, g : GeneratoreDiMatrici) : boolean
Applicatore esegue la sua funzione chiedendo al pallino se almeno una delle
matrici generate da GeneratoreDiMatrici sia un cerchio:
class Applicatore
+esisteUnCerchioRosso(p : Pallino, g : GeneratoreDiMatrici) : boolean
{
per ogni MatriceQuadrataDiPixel M nella ListaDiMatriciQuadrateDiPixel di g
se p èUnCerchio(M) allora return true
return false
}
Mi segui? Ti sconfiffera l'idea?
6 devastante... xò sinceramente non ti ho seguito molto dato che non le abbiamo ancora studiate le classi... Comunque mi avrebbero suggerito un altro metodo che forse dico forse è + facile... Hai presente che quando prendi un immagine clicchi "apri con" e poi usi il blocco note per aprirla ti viene fuori il file header (si dice così vero?) non si potrebbe estrapolare la posizione del pallino all' interno della pagina da quel file? così sarebbe + semplice, dato che si lavora con dei caratteri e non con delle immagini. Cosa ne dici?
Potrebbe non essere così semplice.
Dipende da cosa intendiamo per "pallino" e "posizione".
Ad esempio è relativamente facile se il pallino è un'imagine esterna incorporata in un nodo del documento html avente posizione assoluta.
Cerchi nel file sorgente finchè non trovi il nome del file immagine del pallino (tipo "pallino.gif") poi prendi la posizione del nodo immagine (che sarà "absolute").
Altrimenti è una tragedia. Il sorgente html contiene testo che viene interpretato per riprodurre un contenuto grafico e l'interpretazione di html non è esattamente un lavoretto di una mezza giornata :D.
no allora ti spiego il pallino ogni volta che clicco un tasto cambia posizione ma dal sorgente html non si riesce ad individuare la sua posizione, quindi quello che volevo fare io era uno stamp e poi analizzare l' immagine. Per fare questo volevo aprire l' immagine ottenuta con il tasto stamp con il blocco note e attraverso il file header capire dov'è il pallino rosso... capito?
Stamp genera un'immagine bitmap: cioè una valanga di numeri e basta.
Diverso sarebbe se l'immagine fosse di tipo vettoriale in formato svg. Allora avresti un "testo da leggere".
Se provi a fare uno stamp, aprire paint, copiare l'immagine, salvarla su un file e poi aprirla con blocco note vedrai cosa intendo per valanga di numeri.
si è vero... come si fa allora ad ottenere un immagine in formato svg?
grazie ancora per il tuo aiuto
se vuoi ti aggiungo in msn così facciamo prima a capirci...
comunque uno di questi software potrebbe essere di aiuto?
http://www.masternewmedia.org/it/2005/03/13/convertire_da_bitmap_a_vettoriale.htm
L'idea non è irrealizzabile ma non so quanto sia affidabile. Il fatto è che la trasformazione di un'immagine bitmap in forma vettoriale è un'interpretazione più che una conversione: non è detto che il cerchio salti fuori, anche se è molto probabile.
Puoi comunque provare a vedere quale sia il risultato della trasformazione vettoriale di uno screenshot di una pagina html con un programma tipo Inkscape: fai uno stamp, lo incolli in Inkscape e poi lo converti in SVG.Apri il file SVG con un editor di testo e vedi se compaia qualche elemento che suggerisce la presenza del cerchio che vuoi trovare.
nessun risultato con inkheart quindi credo che sia necessario tornare all' idea originaria: quella del confronto di pixel... Xò io non so proprio da dove iniziare non è che mi potresti dare una spinta?
grazie in anticipo:D
OT:
se vuoi ti aggiungo in msn così facciamo prima a capirci...
:rotfl:
tipico esempio di comunicazione tra un bimbominkia con la K e un esperto con i cosiddetti :D
da notare il nonscialáns con cui l'esperto, che probabilmente non ha mai usato MSN in vita sua ne' tantomeno vuole un accollo che gli chieda consigli informatici in tempo reale 24/7, glissa la frase quotata :asd:
scusatemi ma proprio non resistevo :D
borelg, PGI-Bis non é una fighetta trovata su qualche Live Space pieno di fotografie di ragazze-triglia* :)
* cioé ragazze che tirano sempre bacetti all'obiettivo quando fanno le foto; possibilmente con il volto a tre quarti.
nessun risultato con inkheart :asd:
tomminno
01-03-2009, 23:21
Ciao a tutti oggi ho da proporvi 1 progetto che non so se sia realizzabile... Quello che vorei fare io sarebbe creare un programma che riesca ad individuare un pallino rosso sempre della stessa dimensione, colore e forma all' interno di una pagina web o di una immagine a seconda di quale delle due è più semplice da realizzare e a restituirne la posizione.
Il problema è che non so proprio da dove partire, non è cqualcuno conosce qualche funzione che mi potrebbe essere utile?
grazie i anticipo.
Lo vedo un lavoro adatto per le reti neurali, ma se non hai ancora studiato le classi (cosa hai studiato di C++?) la vedo dura, mica perchè non si possa fare anche in C, è solo perchè il tuo livello di conoscenze sembra non essere ad un livello tale da potersi confrontare con tale tipologia di problemi.
Problema che indipendentemente dal linguaggio comunque non è proprio di semplice risoluzione.
Lo è relativamente su una immagine (dipende da cos'altro è presente), ma su una pagina web, la vedo dura, anche perchè se il contenuto della pagina è flottante la posizione potrebbe cambiare a seconda della dimensione della finestra del browser.
Inoltre metti che la pagina o l'immagine che elabori contenga anche qualcosa come questo: " :mad: " il tuo programma facilmente lo scambierebbe per il pallino rosso da trovare.
Figurati io all'università ho passato qualche mese a cercare cartelli stradali nelle foto e si trattava in prima battuta di individuare triangoli rossi, cerchi rossi e cerchi blu, poi una rete neurale adeguatamente ammaestrata mi indicava il tipo specifico di cartello.
Riconoscere che una mela rossa bella tonda con il riflesso del flash al centro non era il cartello di divieto d'accesso ha richiesto un pò di lavoro.
Per l'elaborazione avanzata di immagini in C/C++ potresti provare con OpenCV della Intel.
Ci sono già pronte funzioni per l'estrazione dei contorni da una immagine, da lì poi bisogna vedere quali tra i contorni individuati si avvicinano il più possibile ad una circonferenza (se ti sei mai chiesto se gli esercizi di matematica sulle circonferenze avessero una qualche applicazione pratica eccoti servito).
Volendo semplificare il problema basterebbe a quel punto vedere quanto rosso c'è all'interno delle aree individuate come circonferenze.
Ti faccio un riassunto super espresso riguardante le classi, omettendo tutto ciò che non interessa ai fini della realizzazione di questo trova cerchi.
Negherò inoltre di averlo mai fatto: la faccenda è molto più interessante di quanto dirò ma è anche più lunga.
"Le classi sono un modo per impacchettare funzioni e variabili" (Alan Kay perdonami).
C'è una ragione per cui "impacchettare funzioni" ha un senso che deriva da un punto di vista che si può assumere quando si vuole scrivere un programma. Non mi dilungo sulla questione.
Una volta che hai definito una classe puoi usarla per creare delle variabili che possiedono le funzioni e le variabili definite nella classe che hai usato.
Io creo una classe, gli infilo dentro una funzione che dice "pippo" e con quella classe posso creare una variabile che dice pippo.
Le classi in C++ sono facilissime.
C'è un file di intestazione che dichiara quali variabili e funzioni ha la classe e un file sorgente in cui scrivi la definizione delle funzioni.
Prendiamo il Pixel di cui parlavo. Più che un pixel è un colore ma m'è venuto pixel, prendiamolo per buono.
Uso la notazione UML per dire che un Pixel è fatto così:
class Pixel
+getRosso() : int
+getVerde() : int
+getBlu() : int
Significa, lasciando da parte qualcosa, "Pixel è una classe che ha tre funzioni membro"
La prima si chiama getRosso() ed è una funzione senza argomenti che restituisce un intero. La seconda si chiama getVerde() ed è una funzione che restituisce un intero. La terza si chiama getBlu() e fa la stessa cosa delle altre due.
In C++ quella roba si può tradurre con il file di intestazione Pixel.h:
#ifndef PIXEL_H
#define PIXEL_H
class Pixel {
private:
int rosso;
int verde;
int blu;
public:
Pixel(int, int, int);
int getRosso();
int getVerde();
int getBlu();
};
#endif
e il file sorgente Pixel.cpp:
#include "Pixel.h"
Pixel::Pixel(int r, int v, int b) {
rosso = r;
verde = v;
blu = b;
}
int Pixel::getRosso() {
return rosso;
}
int Pixel::getVerde() {
return verde;
}
int Pixel::getBlu() {
return blu;
}
Ora posso usare la classe Pixel per creare quante variabili di tipo Pixel voglio. Ognuna di quelle variabili avrà le tre funzioni che io ho definito per la classe Pixel.
La funzione in grassetto è "speciale", si chiama costruttore e serve per obbligare chi voglia creare istanze della classe Pixel a farlo dando un valore alle tre variabili rosso verde e blu conservate nel pixel creato.
Per creare un'istanza di Pixel (una variabile di tipo Pixel) posso dire:
Pixel p(10, 20,30)
Per usare le funzioni di p uso l'operatore "." (un punto):
int x = p.getRosso(); //x vale 10
int y = p.getVerde(); //y vale 20
int z = p.getBlu(); //z vale 30
Ad esempio:
#include <iostream>
#include "Pixel.h"
using namespace std;
int main(int argc, char *argv[])
{
Pixel p(10, 10, 10);
cout << "rosso" << p.getRosso() << "\n";
cout << "verde" << p.getVerde() << "\n";
cout << "blu" << p.getBlu() << "\n";
system("PAUSE");
}
Ci sei fin qui?
si ho capito quasi tutto e leggendo il tuo post solo 1 volta... dovresti fare l' insegnante :D Comunque fin qua ci sono perfettamente. In poche parole con le classi io posso creare nuovi tipi di variabili che al loro interno hanno varie funzioni o parametri giusto?
Ora manca la parte di getrosso getblu getverde perchè io per ora in c++ ho lavorato solamente con caratteri e numeri, mai con immagini...
Grazie mille per le tue spiegazioni... :D sono in attesa della prossima lezione..
mi sono dimenticato di chiederti anche 1 altra cosa... ma quelle funzioni che si trovano all' interno della classe come le creo ovvero che tipo di funzioni sono normali? e a cosa servirebbero
In attesa di una tua risposta :)
grazie ancora in anticipo
forse ho trovato una soluzione alternativa + semplice getpixel() è una funzione che serve per determinare il colore di un certo pixel. Quindi mi basta fare un ciclo for + questa funzione per riuscire a trovare il colore rosso (dato che come elemento rosso c'è solo il pallino) in una determinata area. Il problema però è dato che il colore del pixel lo devo prendere dalla schermata di firefox dovrei usare la funzione findwindow per operare su quella li giusto? Però se compilo il mio codice mi da sempre come ritorno le componenti rosso verde e blu del colore del pixel della schermata dalla quale viene fatto partire l' eseguibile, ovvero se metto l' eseguibile sul desktop mi da il colore di quel pixel del desktop, se lo metto in 1 nuova cartella e la ingrandisco a tutto schermo mi da bianco dato che il pixel centrale (quello che ho scelto io ) è bianco perchè la cartella è vuota... Mi diresti perchè non riesce ad identificare la finestra di firefox nonostante io gli abbia dato il titolo preciso? Ho guardato un po' in giro ed è risultato che dovrei trasformare in titolo da char a wchar possibile? se si come faccio?
Ecco il mio codice:
#include <cstdlib>
#include <iostream>
#include <windows.h>
#include <stdio.h>
using namespace std;
int main()
{
int x,y;
char titolo[]="Mozilla Firefox";
HWND firefox = FindWindow(NULL,titolo);
x = 640;
y = 512;
HDC ff = GetDC(firefox);
COLORREF color = GetPixel(ff, x, y);
BYTE r, g, b;
r = GetRValue(color);
g = GetGValue(color);
b = GetBValue(color);
printf ("R=%i\nG=%i\nB=%i\n",r,g,b);
system("PAUSE");
return EXIT_SUCCESS;
}
grazie mille in anticipo :D
Eccoci qua.
Tieni conto che la faccenda delle classi ha un significato un tantinello meno arbitrario di come la sto buttando giù in questo thread. E' per brevità che la faccio breve.
Per noi le funzioni definite all'interno delle classi sono funzioni normali nel senso che fanno quello che fa qualsiasi funzione. Hanno un che di speciale nel fatto che non sono direttamente invocabili. Non posso dire:
class Pippo {
public:
int funzione() {
return 10;
}
}
E cercare di richiare funzione in una qualsiasi altro file sorgente semplicemente scrivendo:
int x = funzione();
Per poter usare le funzioni definite in una classe devo avere per le mani un'istanza di quella classe. Devo quindi dire:
Pippo istanza;
int x = istanza.funzione();
oppure:
Pippo* istanza = new Pippo();
int x = istanza->funzione();
Ricordo che istanza è un nome, convenzionale, che si usa per definire variabili il cui tipo è una classe.
E' come se dicessimo che nell'espressione:
int x = 10;
"x" è istanza di "int".
Ancora una volta vorrei "grattare la superficie" e nulla più perchè divagare ecessivamente ti distoglierebbe dallo specifico compito che devi portare a termine.
Giusto per accenno, questa curiosità dell'avere uno strumento che permette di definire delle funzioni agglomerandole in un pacchetto denominato (la classe ha un nome liberamente scelto da chi la scriva) assume un senso allorchè aderiamo ad una certa teoria riguardante il modo in cui le cose dovrebbero essere rappresentate per risultare immediatamente comprensibili ad un essere umano.
E' solo una teoria, e neppure troppo fondata perchè nasce un bel po' di tempo fa quando ancora certe cose non si sapevano o, meglio, si sapevano cose che poi si sono rilevate non del tutto corrette.
Insomma, le classi sono uno strumento di rappresentazione delle cose da un certo punto di vista. Il fatto che le classi possano avere funzioni membro dipende da quel punto di vista.
ok?
ok ho capito...
prova a dare 1 occhiata al post che ho inviato contemporaneamente a te nella prima pagina ;) forse ho trovato un altra soluzione più diretta...
cosa ne dici?
grazie mille ancora per le tue spiegazioni
up x favore... non riesco a capire dove sbaglio:muro: :muro:
non sono un esperto di API Windows ma direi che non sbagli da nessuna parte. Sicuro che il titolo della finestra sia esattamente "Mozilla Firefox"? Il firefox che ho io ci mette anche il titolo della pagina, tipo:
"Google - Mozilla Firefox"
si è esatto il titolo.. boh secondo me sbaglio qualcosa... comunque per quanto riguarda la gestione del browser ho sentito parlare della libreria urlmon.h che mi permetterebbe di gestirlo con facilità possibile?
grazie ancora
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.