Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab 基于图像处理的纸币识别_Matlab_Image Processing_Computer Vision_Image Segmentation_Image Recognition - Fatal编程技术网

Matlab 基于图像处理的纸币识别

Matlab 基于图像处理的纸币识别,matlab,image-processing,computer-vision,image-segmentation,image-recognition,Matlab,Image Processing,Computer Vision,Image Segmentation,Image Recognition,在纸币中,我想检查条带是否断裂或实线。为此,我拍了一张背景为强光的照片。我得到了以下两张照片,一张是真币,另一张是假币。我在条纹存在的位置裁剪图像,并进行开合重建,最后计算黑色像素。但结果并不是我想要的。有什么帮助吗 以下是图片: 这是我在判断你的钞票是真是假方面的一次相当拙劣的尝试。我注意到两个音符之间的一件事是,真实音符的细条或多或少是连续的,而假条在细条中有零碎的细线。可以说,假音符在薄条中有多行,而真音符只有一行。让我们试着得到我们的图像,这样我们就可以检测到条纹本身(正如您也尝试过

在纸币中,我想检查条带是否断裂或实线。为此,我拍了一张背景为强光的照片。我得到了以下两张照片,一张是真币,另一张是假币。我在条纹存在的位置裁剪图像,并进行开合重建,最后计算黑色像素。但结果并不是我想要的。有什么帮助吗

以下是图片:


这是我在判断你的钞票是真是假方面的一次相当拙劣的尝试。我注意到两个音符之间的一件事是,真实音符的细条或多或少是连续的,而假条在细条中有零碎的细线。可以说,假音符在薄条中有多行,而真音符只有一行。让我们试着得到我们的图像,这样我们就可以检测到条纹本身(正如您也尝试过的那样),并计算我们看到的线条数。如果我们只看到一行,它是真的,但如果我们看到多行,它是假的。我将通过中间图像向您介绍我是如何做到这一点的

步骤#1-读入图像(当然) 我将直接从StackOverflow中读取您的图像
imread
非常适合从在线URL读取图像:

%%//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
第2步-将图像分解为HSV并进行分析 我注意到的一件事是,条子很暗,而钞票的颜色主要是绿色。我使用了一些基本的彩色图像处理作为预处理步骤。我将图像转换为HSV(),并分别查看了每个组件:

%% 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');
以下是图像的外观:

在这段代码中,我将分别为色调、饱和度和值并排显示每个组件。你会注意到一些非常奇怪的事情。黑色薄条具有相当高的饱和度,这是有道理的,因为黑色可以被视为是纯饱和度的“颜色”(没有白光)。“值”组件的条形图的值非常低,这也有意义,因为“值”捕捉颜色的亮度/强度

步骤#3-设置饱和度和值平面的阈值以创建二值图像 通过上面的观察,我将在饱和度和值平面上对图像进行阈值设置。任何具有相当高的组合饱和度和相当低的值的点都是黑色条带的候选点。我将自己裁剪出条带,使事情变得更容易(正如你已经做的那样)。请注意,每个图像中条带的位置不同,因此我必须进行相应的调整。我只提取了正确的列,而保留了相同的行和切片。这些饱和度和值阈值是非常特别的,所以我不得不使用它们来获得好的结果

%%//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');
这些是图像的外观:

第5步-最终清理 您会注意到,对于每个图像,边缘上都有一些噪声像素。因此,让我们使用一个区域打开。此函数用于删除黑白图像中小于特定区域的像素区域。我将选择15来去除边缘上不属于条带的像素。因此:

%%//Area open the image
figure;
areaopenReal = bwareaopen(BWImageCloseReal, 15);
imshow(areaopenReal);
title('Real');
figure;
areaopenFake = bwareaopen(BWImageCloseFake, 15);
imshow(areaopenFake);
title('Fake');
以下是图像的外观:

第6步-计算黑线的数量 最后一步是简单地计算每个图像中黑线的数量。如果只有1,这表示钞票是真的,而如果超过1,这表示钞票是假的。我们可以使用第二个参数来计算有多少个对象。换言之:

%%//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)]);
我们在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
正如你所看到的,真实的音符只有一行,而虚假的音符有不止一行。您将不得不根据您必须使用的纸币来使用此代码,但这是一个开始


完整代码 为了完整起见,这里是完整的代码,您可以自己复制、粘贴并在MATLAB中运行

%%//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)]);

请记住,为了满足您的目的,您必须使用这些参数。以下是每一步的数字:

。。。最后是对象计数:

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


祝你好运

这是我试过的。在这种方法中,允许在线段周围使用一些保护带,而不是将区域限制为线段的宽度,这一点很重要

  • 加载rgb图像
  • 关闭rgb图像,以便删除或消除较暗的线段,然后将此关闭图像转换为灰度(我们称之为im1
  • 将rgb图像转换为灰度,然后增强对比度(我们称之为im2)
  • 取两者之差:im1-im2
  • 以这个差异图像的投影为例。这会给你一个一维信号
  • 您还可以平滑此信号
  • 设置阈值并找到分段数
  • 对于折线图像,应该获得更多的分段
以下是给定示例图像的结果:

输入图像:

差异图像:

预测和细分:

下面是Matlab代码:

clear all;
close all;

imt = imread('t.jpg');
imf = imread('f.jpg');
% convert to gray scale
grt = rgb2gray(imt);
grf = rgb2gray(imf);
% contrast enhance the gray image to emphasize dark lines in lighter background
grt = imadjust(grt);
grf = imadjust(grf);
% close rgb. choose a larger k. idea is to remove the dark line
k = 7;
se = ones(k);
imtcl = imclose(imt, se);
imfcl = imclose(imf, se);
% convert closed image to gray scale
grtcl = rgb2gray(imtcl);
grfcl = rgb2gray(imfcl);
% take the difference (closed-gray-scale - contrast-enhanced-gray-scale)
difft = grtcl - grt;
difff = grfcl - grf;
% take the projection of the difference
pt = sum(difft');
pf = sum(difff');
% smooth the projection
ptfilt = conv(pt, ones(1, k)/k, 'same');
pffilt = conv(pf, ones(1, k)/k, 'same');
% threshold (multiplication by max element is just for visualization)
tht = (pt > graythresh(pt))*max(pt);
thf = (pf > graythresh(pf))*max(pf);
% get the number of segments. we should get more segments for the broken line (nt < nf)
[lblt, nt] = bwlabel(tht);
[lblf, nf] = bwlabel(thf);

figure,
subplot(2, 1, 1), imshow(difft'), title('difference image for solid line')
subplot(2, 1, 2), imshow(difff'), title('difference image for broken line')

figure,
subplot(2, 1, 1), plot(1:length(pt), pt, 1:length(pt), ptfilt, 1:length(pt), tht),
title('solid line image'),
legend('projection', 'smoothed', 'thresholded', 'location', 'eastoutside')
subplot(2, 1, 2), plot(1:length(pf), pf, 1:length(pf), pffilt, 1:length(pf), thf),
title('broken line image'),
legend('projection', 'smoothed', 'thresholded', 'location', 'eastoutside')
全部清除;
全部关闭;
imt=imread('t.jpg');
imf=imread('f.jpg');
%转换为灰度
grt=RGB2灰色(imt);
grf=RGB2GRY(国际货币基金组织);
%对比度增强灰色图像,以强调较浅背景中的暗线
grt=imadjust(grt);
grf=imadjust(grf);
%关闭rgb。选择一个较大的k。我们的想法是消除暗线
k=7;
se=一(k);
imtcl=imclose(imt,se);
imfcl=imclose(imf,se);
%将闭合图像转换为灰度
grtcl=rgb2gray(imtcl);
grfcl=RGB2灰色(imfcl);
%取差值(闭合灰度-对比)
%% //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)]);
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
clear all;
close all;

imt = imread('t.jpg');
imf = imread('f.jpg');
% convert to gray scale
grt = rgb2gray(imt);
grf = rgb2gray(imf);
% contrast enhance the gray image to emphasize dark lines in lighter background
grt = imadjust(grt);
grf = imadjust(grf);
% close rgb. choose a larger k. idea is to remove the dark line
k = 7;
se = ones(k);
imtcl = imclose(imt, se);
imfcl = imclose(imf, se);
% convert closed image to gray scale
grtcl = rgb2gray(imtcl);
grfcl = rgb2gray(imfcl);
% take the difference (closed-gray-scale - contrast-enhanced-gray-scale)
difft = grtcl - grt;
difff = grfcl - grf;
% take the projection of the difference
pt = sum(difft');
pf = sum(difff');
% smooth the projection
ptfilt = conv(pt, ones(1, k)/k, 'same');
pffilt = conv(pf, ones(1, k)/k, 'same');
% threshold (multiplication by max element is just for visualization)
tht = (pt > graythresh(pt))*max(pt);
thf = (pf > graythresh(pf))*max(pf);
% get the number of segments. we should get more segments for the broken line (nt < nf)
[lblt, nt] = bwlabel(tht);
[lblf, nf] = bwlabel(thf);

figure,
subplot(2, 1, 1), imshow(difft'), title('difference image for solid line')
subplot(2, 1, 2), imshow(difff'), title('difference image for broken line')

figure,
subplot(2, 1, 1), plot(1:length(pt), pt, 1:length(pt), ptfilt, 1:length(pt), tht),
title('solid line image'),
legend('projection', 'smoothed', 'thresholded', 'location', 'eastoutside')
subplot(2, 1, 2), plot(1:length(pf), pf, 1:length(pf), pffilt, 1:length(pf), thf),
title('broken line image'),
legend('projection', 'smoothed', 'thresholded', 'location', 'eastoutside')