Ecco il mio tentativo piuttosto maldestro a determinare se la vostra banconota è falso o reale. Una cosa che ho notato tra le note è che la nota reale ha la sua striscia sottile più o meno continua mentre la striscia finta ha delle linee sottili frammentate nella striscia. Si potrebbe dire che la nota falsa ha più di una riga nella striscia sottile mentre la nota reale ha solo una riga. Proviamo ad ottenere la nostra immagine in modo tale da rilevare la striscia stessa (come hai anche provato) e contiamo quante linee vediamo. Se vediamo solo una riga, è reale, ma se vediamo più di una riga è falsa. Ti guiderò attraverso come l'ho fatto con immagini intermedie in mezzo.
Passo # 1 - Leggere nell'immagine (ovviamente)
ho intenzione di leggere direttamente le immagini in da StackOverflow. imread
è grande per la lettura di immagini da URL online:
%%//Read in image
clear all;
close all;
Ireal = imread('http://i.stack.imgur.com/SqbnIm.jpg'); %//Real
Ifake = imread('http://i.stack.imgur.com/2U3DEm.jpg'); %//Fake
Passo # 2 - Scomporre immagine in HSV e analizzare
Una cosa che ho notato è che le strisce sono molto scuri, mentre la banconota è prevalentemente verde a colori Ho usato alcune immagini base per l'elaborazione delle immagini come fase di pre-elaborazione. Ho trasformato l'immagine in HSV (Hue-Saturation-Value) e ha preso uno sguardo a ogni componente separatamente:
%% Pre-analysis
hsvImageReal = rgb2hsv(Ireal);
hsvImageFake = rgb2hsv(Ifake);
figure;
imshow([hsvImageReal(:,:,1) hsvImageReal(:,:,2) hsvImageReal(:,:,3)]);
title('Real');
figure;
imshow([hsvImageFake(:,:,1) hsvImageFake(:,:,2) hsvImageFake(:,:,3)]);
title('Fake');
Ecco quello che le immagini assomigliano:
In questo codice , Sto visualizzando ciascuno dei componenti l'uno accanto all'altro per la tonalità, la saturazione e il valore rispettivamente. Noterai qualcosa di molto particolare. La striscia nera sottile ha una saturazione abbastanza elevata, il che ha senso in quanto il nero può essere considerato un "colore" che è pura saturazione (privo di luce bianca). Il componente del valore ha la sua striscia con valori molto bassi, il che ha anche senso quando il valore cattura la luminosità/intensità del colore.
Passo # 3 - Soglia la saturazione e il valore piani per creare un'immagine binaria
con le osservazioni che ho fatto in precedenza, ho intenzione di soglia l'immagine guardando gli aerei di saturazione e di valore. Qualsiasi punto che abbia una saturazione combinata piuttosto elevata e valori piuttosto bassi sono candidati che fanno parte della striscia nera. Ho intenzione di ritagliare solo le strisce da sole per rendere le cose più facili (come hai già fatto anche tu). Prendi nota del fatto che la posizione delle strisce in ogni immagine è diversa, quindi mi sono dovuto adeguare di conseguenza. Ho semplicemente estratto le colonne giuste, lasciando le righe e le sezioni uguali.Queste soglie di saturazione e valore sono piuttosto ad-hoc, quindi ho dovuto giocare con queste per ottenere buoni risultati.
%%//Initial segmentation
croppedImageReal = hsvImageReal(:,90:95,:);
croppedImageFake = hsvImageFake(:,93:98,:);
satThresh = 0.4;
valThresh = 0.3;
BWImageReal = (croppedImageReal(:,:,2) > satThresh & croppedImageReal(:,:,3) < valThresh);
figure;
subplot(1,2,1);
imshow(BWImageReal);
title('Real');
BWImageFake = (croppedImageFake(:,:,2) > satThresh & croppedImageFake(:,:,3) < valThresh);
subplot(1,2,2);
imshow(BWImageFake);
title('Fake');
questi sono ciò che le immagini assomigliano:
Si può vedere che il vero striscia più o meno ha più la connettività rispetto alla striscia di falso. Facciamo un po 'di più di elaborazione per pulire questo
Passo # 4 - Fare qualche chiusure minori
Se si dà un'occhiata alla sottile striscia nera della nota falso, vedrete che ogni linea nera è separati da alcuni pixel mentre la nota reale non ha alcuna separazione. Tuttavia, vedrai che nella striscia reale sopra, ci sono ancora alcune parti della linea che sono disconnesse. Come tale, proviamo a collegare la linea insieme. Questo è sicuro perché se dovessimo farlo sull'immagine falsa, le parti della striscia sono così distanti che la chiusura non dovrebbe fare la differenza, ma aiuterà nella nostra analisi delle immagini reali. Come tale, ho chiuso queste immagini con una linea di 6 pixel che è verticale. Ecco il codice per farlo:
%%//Post-process
se = strel('line', 6, 90);
BWImageCloseReal = imclose(BWImageReal, se);
BWImageCloseFake = imclose(BWImageFake, se);
figure;
subplot(1,2,1);
imshow(BWImageCloseReal);
title('Real');
subplot(1,2,2);
imshow(BWImageCloseFake);
title('Fake');
questi sono ciò che le immagini assomigliano:
Passo # 5 - pulizia finale
Si noterà che per ciascuno dei immagini, ci sono alcuni pixel rumorosi sui bordi. Come tale, usiamo un'area che si apre attraverso bwareaopen
. Questa funzione rimuove le aree dei pixel in un'immagine in bianco e nero con meno di una determinata area. Vado a scegliere 15 per eliminare i pixel lungo i bordi che non appartengono alla striscia. In quanto tale:
%%//Area open the image
figure;
areaopenReal = bwareaopen(BWImageCloseReal, 15);
imshow(areaopenReal);
title('Real');
figure;
areaopenFake = bwareaopen(BWImageCloseFake, 15);
imshow(areaopenFake);
title('Fake');
Ecco quello che le immagini assomigliano:
Passo # 6 - Contare il numero di linee nere
L'ultimo passo è quello di contare semplicemente il numero di linee nere in ogni immagine. Se c'è solo 1, questo indica che la banconota è reale, mentre se c'è più di 1, questo indica che la banconota è falsa. Possiamo usare bwlabel
e usare il secondo parametro per contare quanti oggetti ci sono. In altre parole:
%%//Count how many objects there are
[~,countReal] = bwlabel(areaopenReal);
[~,countFake] = bwlabel(areaopenFake);
disp(['The total number of black lines for the real note is: ' num2str(countReal)]);
disp(['The total number of black lines for the fake note is: ' num2str(countFake)]);
Abbiamo ottenere il seguente output in MATLAB:
The total number of black lines for the real note is: 1
The total number of black lines for the fake note is: 4
Come si può vedere, la vera nota ha una sola linea, mentre la nota falsa ha più di una. Dovrai giocare con questo codice a seconda di quale banconota devi far funzionare, ma questo è un punto da cui iniziare.
codice completa
Solo per completezza, ecco il codice completo in modo da poter copiare e incollare ed eseguire in MATLAB te stesso.
%%//Read in image
clear all;
close all;
Ireal = imread('http://i.stack.imgur.com/SqbnIm.jpg'); % Real
Ifake = imread('http://i.stack.imgur.com/2U3DEm.jpg'); % Fake
%%//Pre-analysis
hsvImageReal = rgb2hsv(Ireal);
hsvImageFake = rgb2hsv(Ifake);
figure;
imshow([hsvImageReal(:,:,1) hsvImageReal(:,:,2) hsvImageReal(:,:,3)]);
title('Real');
figure;
imshow([hsvImageFake(:,:,1) hsvImageFake(:,:,2) hsvImageFake(:,:,3)]);
title('Fake');
%%//Initial segmentation
croppedImageReal = hsvImageReal(:,90:95,:);
croppedImageFake = hsvImageFake(:,93:98,:);
satThresh = 0.4;
valThresh = 0.3;
BWImageReal = (croppedImageReal(:,:,2) > satThresh & croppedImageReal(:,:,3) < valThresh);
figure;
subplot(1,2,1);
imshow(BWImageReal);
title('Real');
BWImageFake = (croppedImageFake(:,:,2) > satThresh & croppedImageFake(:,:,3) < valThresh);
subplot(1,2,2);
imshow(BWImageFake);
title('Fake');
%%//Post-process
se = strel('line', 6, 90);
BWImageCloseReal = imclose(BWImageReal, se);
BWImageCloseFake = imclose(BWImageFake, se);
figure;
subplot(1,2,1);
imshow(BWImageCloseReal);
title('Real');
subplot(1,2,2);
imshow(BWImageCloseFake);
title('Fake');
%%//Area open the image
figure;
areaopenReal = bwareaopen(BWImageCloseReal, 15);
subplot(1,2,1);
imshow(areaopenReal);
title('Real');
subplot(1,2,2);
areaopenFake = bwareaopen(BWImageCloseFake, 15);
imshow(areaopenFake);
title('Fake');
%%//Count how many objects there are
[~,countReal] = bwlabel(areaopenReal);
[~,countFake] = bwlabel(areaopenFake);
disp(['The total number of black lines for the real note is: ' num2str(countReal)]);
disp(['The total number of black lines for the fake note is: ' num2str(countFake)]);
Edit - 4 Settembre 2014
Lei mi ha contattato e voleva sapere come rilevare la grande striscia nera che si trova a destra di ogni nota. Questo non è poi così male da fare. L'immagine che hai postato è l'altra nota falsa di dimensioni diverse rispetto alle altre. In quanto tale, ridimensionerò questa immagine in modo che questa immagine abbia all'incirca le stesse dimensioni delle altre che hai mostrato. Questa è l'immagine che hai postato nei commenti:
Osservando tutte le note, che oscillano fra la colonna 195 ° alla colonna 215i. Questo presuppone che ogni immagine abbia 320 colonne. Ora, il processo alla base del modo in cui rilevo se la banconota è falsa è guardando l'intensità complessiva della striscia nera stessa. Noterai che le note false non hanno una striscia nera, o la striscia è piuttosto opaca e sbiadita. Possiamo certamente usarlo a nostro vantaggio. Ecco una breve lista di quello che ho fatto per rilevare la striscia nera:
- Leggi nelle immagini e ridimensionarle per tutte le stesse colonne, quando necessario
- Estrarre il 195 ° alle colonne 215 ° per tutte le immagini
- Converti le immagini in scala di grigi usando
rgb2gray
- Soglia le immagini utilizzando il livello di intensità 30. Ho usato 30 euristicamente perché era principalmente l'intensità che ho visto che consisteva nella striscia nera. Quindi inverti le immagini in modo che il nero diventi bianco. Ho bisogno che la striscia nera diventi bianca per ulteriori analisi. Io uso
im2bw
per fare questo.
- L'area I apre l'immagine come prima, ma specifica un'area più ampia di circa 100 per garantire di eliminare eventuali pixel spuri rumorosi e isolati.
- Faccio una chiusura utilizzando un elemento di struttura quadrata di 5 x 5 per garantire che tutte le regioni disconnesse che si trovano in prossimità di regioni più grandi siano collegate tra loro.
- Conto quindi il numero totale di oggetti rimasti. Se il conteggio è diverso da 1, allora è una nota falsa. Se è solo 1, allora è una nota reale.
Ecco il codice completo:
%% //Read in images
clear all;
close all;
Ireal = imread('http://i.stack.imgur.com/SqbnIm.jpg'); % Real
Ifake = imread('http://i.stack.imgur.com/2U3DEm.jpg'); % Fake
Ifake2 = imread('http://i.imgur.com/SVJrwaV.jpg'); % Fake #2
% //Resize so that we have the same dimensions as the other images
Ifake2 = imresize(Ifake2, [160 320], 'bilinear');
%% //Extract the black strips for each image
blackStripReal = Ireal(:,195:215,:);
blackStripFake = Ifake(:,195:215,:);
blackStripFake2 = Ifake2(:,195:215,:);
figure(1);
subplot(1,3,1);
imshow(blackStripReal);
title('Real');
subplot(1,3,2);
imshow(blackStripFake);
title('Fake');
subplot(1,3,3);
imshow(blackStripFake2);
title('Fake #2');
%% //Convert into grayscale then threshold
blackStripReal = rgb2gray(blackStripReal);
blackStripFake = rgb2gray(blackStripFake);
blackStripFake2 = rgb2gray(blackStripFake2);
figure(2);
subplot(1,3,1);
imshow(blackStripReal);
title('Real');
subplot(1,3,2);
imshow(blackStripFake);
title('Fake');
subplot(1,3,3);
imshow(blackStripFake2);
title('Fake #2');
%% //Threshold using about intensity 30
blackStripRealBW = ~im2bw(blackStripReal, 30/255);
blackStripFakeBW = ~im2bw(blackStripFake, 30/255);
blackStripFake2BW = ~im2bw(blackStripFake2, 30/255);
figure(3);
subplot(1,3,1);
imshow(blackStripRealBW);
title('Real');
subplot(1,3,2);
imshow(blackStripFakeBW);
title('Fake');
subplot(1,3,3);
imshow(blackStripFake2BW);
title('Fake #2');
%% //Area open the image
figure(4);
areaopenReal = bwareaopen(blackStripRealBW, 100);
subplot(1,3,1);
imshow(areaopenReal);
title('Real');
subplot(1,3,2);
areaopenFake = bwareaopen(blackStripFakeBW, 100);
imshow(areaopenFake);
title('Fake');
subplot(1,3,3);
areaopenFake2 = bwareaopen(blackStripFake2BW, 100);
imshow(areaopenFake2);
title('Fake #2');
%% //Post-process
se = strel('square', 5);
BWImageCloseReal = imclose(areaopenReal, se);
BWImageCloseFake = imclose(areaopenFake, se);
BWImageCloseFake2 = imclose(areaopenFake2, se);
figure(5);
subplot(1,3,1);
imshow(BWImageCloseReal);
title('Real');
subplot(1,3,2);
imshow(BWImageCloseFake);
title('Fake');
subplot(1,3,3);
imshow(BWImageCloseFake2);
title('Fake #2');
%% //Count the total number of objects in this strip
[~,countReal] = bwlabel(BWImageCloseReal);
[~,countFake] = bwlabel(BWImageCloseFake);
[~,countFake2] = bwlabel(BWImageCloseFake2);
disp(['The total number of black lines for the real note is: ' num2str(countReal)]);
disp(['The total number of black lines for the fake note is: ' num2str(countFake)]);
disp(['The total number of black lines for the second fake note is: ' num2str(countFake2)]);
Tenete a mente che dovrete giocare con questi parametri in base alle proprie finalità. Ecco quali sono le figure assomigliano ad ogni passo:
...e, infine, contare l'oggetto:
The total number of black lines for the real note is: 1
The total number of black lines for the fake note is: 2
The total number of black lines for the second fake note is: 0
Buona fortuna!
che ha affrontato perfettamente il mio problema. Che ne dici se voglio identificare la striscia più larga nella parte destra della nota, come alcune note false hanno la striscia sottile e non hanno la striscia più larga. Ecco un esempio: http://imgur.com/SVJrwaV – user3472037
@ user3472037 - La striscia più larga è generalmente nella stessa area per tutte le banconote? Se lo è, posso suggerire un altro metodo usando la saturazione e il valore come ho detto prima, ma dovremmo cercare la presenza di una singola striscia/linea. Ciò faciliterà il lavoro se la posizione è più o meno fissa. Fammi sapere! – rayryeng
@raryryeng Sì, l'area più ampia si trova nella stessa area per tutte le banconote a differenza della striscia sottile. – user3472037