图像找茬 matlab,数字图像处理、数学形态学、MATLAB GUI实现简单找茬软件

0、简介

这个小作品是我的数字图像处理课程设计,应用基本的图像处理知识与MATLAB的基本脚本编程,实现一个简单的找茬软件。软件实现过程中使用到的找茬游戏图片来源有“梦幻找茬”、“图图找茬”。如有兴趣的人可以亲自玩下这两个游戏。本程序主要目的是练习数字图像处理的基本知识、数学形态学以及MATLAB语言。由于时间与能力的有限,并没有做的很好,各位大神小踩,谢谢。

1、所需知识

matlab基本语言;

matlab GUI实现;

数字图像处理基本知识;

数学形态学基本知识;

2、算法函数实现过程

883c251897bb807291866f0afc4551c1.png    40847bd54685ec5f5d1c0673ac9d6969.png

3)三通道不相同区域提取

原本课程设计的要求是用彩色转灰度后再提取出不同的区域,但是转换得到的灰度的茬的差异有些存在的不明显,所以最后我选择使用红蓝绿三通道来分离出茬的区域。利用原有的颜色差异来分离出茬的区域成效明显好于灰度图像提取。我这里是直接使用MATLAB内置有的imabsdiff()函数来直接获取各个通道不同的区域。然后将各个通道不同的区域相加起来,再使用imopen(),imclose()函数进行开闭运算。实际的图像看起来是一致的颜色,其实存在有一定的差值,甚至是较大的毛刺,所以必须是使用开闭运算来消除毛刺与噪声。

59d766824f4cfe929e2340141510c813.png

5)MATLAB GUI实现

MATLAB的GUI还是比较简单的,初学者需要注意的就只有

a.初始化函数

b.使用句柄传参、或者设置全局变量传参

c.按键响应事件,实际就是调用的函数

MATLAB的所有显示都可以是控件显示的,如 :set(handles.radiobutton1,’visible’,’off’);  就是设置单选框的隐藏不显示,涉及到的参数键与值都可以在GUI绘制的界面的属性中找到。最后一件事情就是MATLAB的GUI实现之后可以打包成可执行文件,但是需要使用的电脑需要安装编译电脑上的MCRInstaller.exe程序。所以MATLAB的GUI程序几乎是不可能脱离MATLAB运行,因为GUI打包几乎都涉及到MATLAB内置的画图函数,所以目的主机必须要拥有MATLAB整个运行库才可以运行GUI。

bea1f1b7658c4d79094d7e0275d08aaa.png

806194e858bdb080c425ee7d8821c9e2.png

3、找茬算法源码

主文件:

clear

close all;

%%读取图片,并显示

fileName = ‘test14.png’;

img = imread(fileName);

% figure();imshow(img);title(‘原图’);

%获取图片信息

[image_h,image_w,image_c] = size(img);

image_w2 = ceil(image_w/2);

%获取灰度图像

img_gray = rgb2gray(img);

%%对源图片对半竖直分割

img_M1 = zeros(image_h,image_w2,3);

img_M2 = zeros(image_h,image_w2,3);

img_M1 = imcrop(img,[0,0,image_w2,image_h]);

img_M1 = uint8(img_M1);

img_M1_gray = rgb2gray(img_M1);

figure(); imshow(img_M1);title(‘原左图’);

img_M2 = imcrop(img,[image_w2+1,0,image_w2,image_h]);

img_M2 = uint8(img_M2);

img_M2_gray = rgb2gray(img_M2);

figure(); imshow(img_M2);title(‘原右图’);

%%判断是否需要一键找茬

% yijian_flag = 0;

% char = input(‘是否一键找茬,y/n:’,’s’);

% if char==’y’

% yijian_flag = 1;

% end

% num_fine = 0;

% %输入偏移量

% if yijian_flag == 0

% while(~num_fine)

% pic = input(‘请确定要偏移的图,l/r:’,’s’);

% pic_dx = input(‘请输入竖直偏移量(0~8):’);

% pic_dy = input(‘请输入竖直偏移量(0~8):’);

%

% if( ((pic==’l’)| (pic==’r’))&(pic_dx>=0)& (pic_dx=0)& (pic_dy

% num_fine = 1;

% else

% fprintf(‘输入错误,请重新输入!!!n’);

% end

% end

% else

% pic = ‘l’;

% pic_dx = 0;

% pic_dy = 0;

% end

%针对test01.jpg默认值

pic = ‘l’;

pic_dx = 0;

pic_dy = 0;

%%进行图片偏移

img_M1_O = zeros(image_h+pic_dx,image_w2+pic_dy,3);

img_M2_O = zeros(image_h+pic_dx,image_w2+pic_dy,3);

img_M1_O = uint8(img_M1_O);

img_M2_O = uint8(img_M2_O);

img_M1_O(:,:,:) = 255;

img_M2_O(:,:,:) = 255;

if pic==1

for i = 1:image_h

for j = 1:image_w2

img_M1_O(i+pic_dx,j+pic_dy,:) = img_M1(i,j,:);

end

end

for i = 1:image_h

for j = 1:image_w2

img_M2_O(i,j,:) = img_M2(i,j,:);

end

end

else

for i = 1:image_h

for j = 1:image_w2

img_M2_O(i+pic_dx,j+pic_dy,:) = img_M2(i,j,:);

end

end

for i = 1:image_h

for j = 1:image_w2

img_M1_O(i,j,:) = img_M1(i,j,:);

end

end

end

figure();imshow(img_M1_O);title(‘左图偏移后’);

figure();imshow(img_M2_O);title(‘右图偏移后’);

%%计算出左右图片偏差值

img_M1_gray = rgb2gray(img_M1_O);

img_M2_gray = rgb2gray(img_M2_O);

% 根据图片中心锁定图片中心

image_h41 = ceil(image_h/4);

image_w41 = ceil(image_w2/4);

image_h43 = image_h41*3;

image_w43 = image_w41*3;

differ = 255*200*200;

differ = uint32(differ);

dx_min = 0;

dy_min = 0;

tmp = 0;

count = 0;

count = uint32(count);

qiuhe = zeros(600);

qiuhe = uint32(qiuhe);

z = 1;

for dx=-(10+pic_dx):10+pic_dx

for dy=-(10+pic_dy):10+pic_dy

for i=image_h41:image_h43

for j=image_w41:image_w43

tmp = uint32(abs(img_M1_gray(i,j)-img_M2_gray(i+dx,j+dy)));

count = count + tmp;

end

end

qiuhe(z) = count;

z = z+1;

if count0

str = sprintf(‘有茬,茬个数:%d’,n);

title(str, ‘Color’, ‘r’);

else

str = sprintf(‘没有茬’);

title(str, ‘Color’, ‘g’);

end

标定矩形框:

function [state,result]=draw_rect(data,pointAll,windSize,showOrNot)

% 函数调用:[state,result]=draw_rect(data,pointAll,windSize,showOrNot)

% 函数功能:在图像画个长方形框

% 函数输入:data为原始的大图,可为灰度图,可为彩色图

% pointAll 框的左上角在大图中的坐标(每行代表一个坐标),

% 注意:在图中的坐标系为第一列为y,第二列为x(很奇怪的)

% windSize 框的大小 分别表示长宽

% showOrNot 是否要显示,默认为显示出来

% 函数输出:state — 表示程序结果状态

% result – 结果图像数据

if nargin

showOrNot = 0;

end

rgb = [255 0 0]; % 边框颜色

lineSize = 2; % 边框大小,取1,2,3

windSize(1,1)=windSize(1,1);

windSize(1,2) = windSize(1,2);

if windSize(1,1) > size(data,1) ||…

windSize(1,2) > size(data,2)

state = -1; % 说明窗口太大,图像太小,没必要获取

disp(‘the window size is larger then image…’);

return;

end

result = data;

if size(data,3) == 3

for k=1:3

for i=1:size(pointAll,1) %画边框顺序为:上右下左的原则

result(pointAll(i,1),pointAll(i,2):pointAll(i,2)+windSize(i,1),k) = rgb(1,k);

result(pointAll(i,1):pointAll(i,1)+windSize(i,2),pointAll(i,2)+windSize(i,1),k) = rgb(1,k);

result(pointAll(i,1)+windSize(i,2),pointAll(i,2):pointAll(i,2)+windSize(i,1),k) = rgb(1,k);

result(pointAll(i,1):pointAll(i,1)+windSize(i,2),pointAll(i,2),k) = rgb(1,k);

if lineSize == 2 || lineSize == 3

result(pointAll(i,1)+1,pointAll(i,2):pointAll(i,2)+windSize(i,1),k) = rgb(1,k);

result(pointAll(i,1):pointAll(i,1)+windSize(i,2),pointAll(i,2)+windSize(i,1)-1,k) = rgb(1,k);

result(pointAll(i,1)+windSize(i,2)-1,pointAll(i,2):pointAll(i,2)+windSize(i,1),k) = rgb(1,k);

result(pointAll(i,1):pointAll(i,1)+windSize(i,2),pointAll(i,2)+1,k) = rgb(1,k);

if lineSize == 3

result(pointAll(i,1)+1,pointAll(i,2):pointAll(i,2)+windSize(i,1),k) = rgb(1,k);

result(pointAll(i,1):pointAll(i,1)+windSize(i,2),pointAll(i,2)+windSize(i,1)+1,k) = rgb(1,k);

result(pointAll(i,1)+windSize(i,2)+1,pointAll(i,2):pointAll(i,2)+windSize(i,1),k) = rgb(1,k);

result(pointAll(i,1):pointAll(i,1)+windSize(i,2),pointAll(i,2)+1,k) = rgb(1,k);

end

end

end

end

end

state = 1;

if showOrNot == 1

figure;

imshow(result);

end

%%这个我是直接使用了网上大神写好的代码修改一下适应找茬实现

%https://blog.csdn.net/loveaborn/article/details/8545809

由于GUI的代码、GUI界面以及源文件过大,我无法直接使用博客园分享,所以稍后给出其他方式分享:

最后我推荐一下博客园里面非常好的数字图像处理的数学形态学处理算法基础的帖子:

http://www.cnblogs.com/tornadomeet/archive/2012/03/20/2408086.html

最后,本人初次写博客,不妥之处望指出,谢谢!

相关资源:软件工程课件软件工程是指研究软件生产的一门学科,也就是将完善的…

来源:既照月白

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2021年2月17日
下一篇 2021年2月17日

相关推荐