gpt4 book ai didi

matlab - 通过图像处理识别纸币

转载 作者:行者123 更新时间:2023-12-04 13:11:17 25 4
gpt4 key购买 nike

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

以下是图片:

enter image description here
enter image description here

%Code for the thine strip
clear all;
close all;
I = imread('IMG_4267.jpg');
imageSize = size(I);
croppedImage = imcrop(I,[300 0 30 570]);
gray=rgb2gray(croppedImage);
se1 = strel('square',2);
I1e = imerode(gray, se1);
I1e = imreconstruct(I1e, gray);
I1b = imdilate(I1e, se1);
I1c = imreconstruct(imcomplement(I1b), imcomplement(I1e));
I1d = imcomplement(I1c);
Edge2=edge(I1d,'canny');
BW1 = im2bw(Edge2);
nBlack = sum(BW1(:));

最佳答案

这是我在确定您的钞票是假的还是真实的方面进行的相当拙劣的尝试。我在音符之间注意到的一件事是,真钞的细条或多或少是连续的,而假条在条中具有碎片化的细线。可以说假钞上有多条线路中细条而实注只有一行 .让我们尝试获取我们的图像,以便我们检测 strip 本身(正如您已经尝试过的那样)并计算我们看到的行数。如果我们只看到一条线,那是真的,但如果我们看到不止一条线,那就是假的。我将带您了解我是如何使用中间图像做到这一点的。

第 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 并进行分析

我注意到的一件事是 strip 很暗,而钞票主要是绿色。我使用了一些基本的彩色图像处理作为预处理步骤。我将图像转换为 HSV ( Hue-Saturation-Value ) 并分别查看了每个组件:
%% 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');

以下是图像的外观:

enter image description here

enter image description here

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

步骤 #3 - 阈值饱和度和值平面以创建二值图像

根据我上面所做的观察,我将根据饱和度和值平面对图像进行阈值处理。任何具有相当高的组合饱和度和相当低的值的点都是黑色 strip 的一部分的候选点。我将自己裁剪出 strip 以使事情变得更容易(正如您已经做过的那样)。请注意,每个图像中 strip 的位置不同,因此我必须相应地进行调整。我只是提取出正确的列,同时保留行和切片相同。这些饱和度和值阈值相当临时,所以我不得不尝试使用这些以获得良好的结果。
%%//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');

这些是图像的样子:

enter image description here

您可以看到真实的 strip 或多或少比假 strip 具有更多的连通性。让我们做更多的处理来清理它

第 4 步 - 做一些小的关闭

如果你看一下假钞的黑色细条,你会发现每条黑线都被相当多的像素隔开,而真正的钞票真的没有分离。但是,您会看到在上面的实际 strip 中,线路的某些部分仍然断开连接。因此,让我们尝试将线路连接在一起。这是安全的,因为如果我们要在假图像上执行此操作,则 strip 的各个部分相距很远,以至于关闭不应该产生任何影响,但这将有助于我们的真实图像分析。因此,我用一条 6 像素的垂直线封闭了这些图像。这是执行此操作的代码:
%%//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');

这些是图像的样子:

enter image description here

第 5 步 - 最后的清理

您会注意到,对于每个图像,边缘都有一些噪声像素。因此,让我们使用通过 bwareaopen 开放的区域。 .此功能删除黑白图像中小于特定区域的像素区域。我将选择 15 来去除不属于 strip 边缘的像素。像这样:
%%//Area open the image
figure;
areaopenReal = bwareaopen(BWImageCloseReal, 15);
imshow(areaopenReal);
title('Real');
figure;
areaopenFake = bwareaopen(BWImageCloseFake, 15);
imshow(areaopenFake);
title('Fake');

以下是图像的外观:

enter image description here

步骤 #6 - 计算黑线的数量

最后一步是简单地计算每个图像中黑线的数量。如果只有1,这表示钞票是真的,而如果大于1,这表示钞票是假的。我们可以使用 bwlabel 并使用第二个参数来计算有多少对象。换句话说:
%%//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)]);

编辑 - 2014 年 9 月 4 日

您联系了我,想知道如何检测每个音符右侧的大黑条。这实际上并没有那么糟糕。您发布的另一张假钞图片与其他图片的大小不同。因此,我将调整该图像的大小,使该图像与您展示的其他图像的大小大致相同。这是您在评论中发布的图片:



通过查看所有笔记,它们会在第 195 列到第 215 列之间徘徊。这是假设每个图像有 320 列。现在,我检测钞票是否是假的背后的过程是通过查看黑条本身的整体强度。您会注意到假钞要么没有黑色 strip ,要么 strip 相当暗淡和褪色。我们当然可以利用这一点。这是我为检测黑条所做的快速列表:
  • 读入图像并在必要时将它们调整为所有相同的列
  • 提取所有图像的第 195 到 215 列
  • 使用 rgb2gray 将图像转换为灰度
  • 使用大约 30 的强度级别对图像进行阈值。我试探性地使用了 30,因为这主要是我看到的黑色 strip 组成的强度。然后反转图像,使黑色变为白色。我需要将黑色 strip 变成白色以进行进一步分析。我用 im2bw 去做这个。
  • 我像以前一样打开图像,但指定了大约 100 的更大区域,以确保我摆脱任何虚假的嘈杂和孤立像素。
  • 我使用 5 x 5 的方形结构元素进行闭合,以确保靠近较大区域的任何断开连接的区域相互连接。
  • 然后我计算剩下的对象总数。如果计数为 不等于 1 ,那就是假纸条。如果它只是 1,那么它就是一个真正的音符。


  • 这是完整的代码:
    %% //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)]);

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

    enter image description here

    enter image description here

    enter image description here

    enter image description here

    enter image description here

    ...最后是对象计数:
    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

    祝你好运!

    关于matlab - 通过图像处理识别纸币,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25580747/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com