当前位置: 首页 > news >正文

数字图像处理作业2

数字图像处理作业

问题一

给定图像car.png和模版图像wheel.png,利用相关检测实现对car图像中的wheel检测,具有最大相关值的位置可以解释为所检测到的wheel位置

算法是利用相关匹配公式,但是原来的公式有一些问题,如果车轮匹配到一个各像素灰度值都较大的区域,可能会有较大的相应输出,得到错误结果。

因此我们对原来的相关公式进行改进,加入了一个归一化的方法。
G ( i , j ) = ∑ u = − k k ∑ v = − l l H ( u , v ) F ( i + u , j + v ) ∑ u = − k k ∑ v = − l l F 2 ( i − u . j − v ) G(i,j)=\frac{\sum^k_{u=-k}\sum^{l}_{v=-l}H(u,v)F(i+u,j+v)}{\sum^k_{u=-k}\sum^{l}_{v=-l}F^2(i-u.j-v)} G(i,j)=u=kkv=llF2(iu.jv)u=kkv=llH(u,v)F(i+u,j+v)
代码展示如下:

因为图像读取的时候默认是uint8的类型,但卷积操作一般结果不止这么大,所以需要将读取的图像数据类型转化成double类型,免得溢出。

% 转变成double类型的
image = double(imread('car.png'));
filter = double(imread('wheel.png'));

接着记录一些长宽和基础的信息,并对原图做padding

%获取图像的长度和宽度
M = size(image,1);
N = size(image,2);

%获取匹配模版的长度和宽度
m=size(filter,1);
n=size(filter,2);
row_middle=(m-1)/2+1;
col_middle=(n-1)/2+1;

%定义一个全0的矩阵和原来的图像大小一致
%为了让卷积操作结束后图像大小一致,因此需要先拓展图片。
Corr_image = zeros([M,N]);
pad_image = padarray(image, [(m-1)/2, (n-1)/2]);

然后计算累积的频次,然后除以总的像素数量乘上灰度数,得到映射的灰度值结果

cum = double(cum);
% 求累计概率,得到累计直方图
for i = 2 : 256
    cum(i) = (cum(i - 1) + cum(i));
end
 
for i = 1 : 256
    cum(i) = cum(i)/(R*C) * 255;
end

% 映射
fy = double(fx);
for i = 1 : R
    for j = 1 : C
        fy(i, j) = cum(fy(i, j) + 1);
    end
end

最后进行卷积操作。这里本来可以使用矩阵乘法的方法来求卷积,效率会更高。但这里因为想感受一下自己实现一遍卷积公式的过程,所以用了循环嵌套的方法。经过测试,效率比用矩阵乘法的要慢,但结果相同。代码如下:

%卷积操作
for i = (1+(m-1)/2):(M+(m-1)/2)
    for j = (1+(n-1)/2):(N+(n-1)/2)
        % 计算一个filter中的卷积和  此部分也可以换成矩阵的点乘形式
        corr_sum=0;normal_sum=0;
        for x = -(m-1)/2:(m-1)/2
           for y = -(n-1)/2:(n-1)/2
               corr_sum=corr_sum+pad_image(i+x,j+y)*filter(row_middle+x,col_middle+y); % 计算公式中的分子部分 卷积和
               normal_sum=normal_sum+pad_image(i+x,j+y); % 计算公式中的分母部分 归一化的和
           end
        end
        Corr_image(i-(m-1)/2,j-(n-1)/2)=corr_sum/normal_sum;
    end
end

在卷积运算后,我们需要对图像进行归一化,因为数值比较大,而且不好设定阈值,所以我们先找到最大值然后令每个元素除以最大值做到归一化的处理。

接着我们设定一个阈值,来选取和轮子相关性最大的点。这里经过测试当阈值为0.85左右的时候,可以检测出4个轮子,如果达到0.95左右只能检测两个轮子,0.98就只能检测出一个轮子,其中第三个轮子的相关值为1,是最大的,因为它和kernal模版完全相同。代码如下:

% 归一化矩阵 并找出阈值大于一定的点
Corr_image=Corr_image./max(max(Corr_image));
res=[];
for i =1+(m-1)/2:M-(m-1)/2
    for j = 1+(n-1)/2:N-(n-1)/2
        if Corr_image(i,j) >0.86
            % 对指向相同轮子的点进行去重
            flag=1;a=size(res,1);
            for index=1:a
               if sqrt((res(index,1)-i)^2+(res(index,2)-j)^2)<10
                   flag=0;break;
               end
            end
            if flag==1
                res=[res;i,j];
            end
            wheel=image(i-(m-1):i+(m-1),j-(n-1):j+(n-1)); % 截取出轮子部分的图像
            imshow(wheel./max(max(wheel)));
        end
    end
end
问题二

第二个问题是:产生椒盐噪声图像,实现采用中值滤波。

产生椒盐噪声的方法如下:

f ( x , y ) = { 255  if  f 0 ( x , y ) > t 1 ( x , y ) 0  if  f 0 ( x , y ) < t 2 ( x , y ) f 0 ( x , y )  otherwise  f(x, y)= \begin{cases}255 & \text { if } f_0(x, y)>t_1(x, y) \\ 0 & \text { if } f_0(x, y)<t_2(x, y) \\ f_0(x, y) & \text { otherwise }\end{cases} f(x,y)= 2550f0(x,y) if f0(x,y)>t1(x,y) if f0(x,y)<t2(x,y) otherwise 

中值滤波就是用3*3的核在原图上做操作,取出核上9个元素的中值作为这个位置的值,起到平滑图像的效果。中值滤波比起均值滤波的在平滑图像上去除噪声的效果经常会更好。

下面进行代码分析:

用上面的公式生成椒盐噪声

% 生成椒盐噪声的图像
noise_image = image;
for i = 1:M
    for j = 1:N
        if image(i,j) > t1(i,j)
            noise_image(i,j) = 255;
        elseif image(i,j) < t2(i,j)
            noise_image(i,j) = 0;
        else
            noise_image(i,j)=image(i,j);
        end
        
    end
end

使用遍历的方法进行中值滤波,每次遍历一个位置,然后用kernal选取9个格子的范围。一维化后进行排序,选取第五个元素作为中值的结果赋值给结果图像对应位置。

% 进行中值滤波操作
pad_image = padarray(noise_image, [(m-1)/2, (n-1)/2]);% 先对原来的图像进行padding
median_image = uint8(zeros([M,N]));
for i = 1:M
    for j = 1:N
        tmp=pad_image(i:i+m-1, j:j+n-1);
        tmp = sort(tmp(:));
        median_image(i,j) = tmp(5);
    end
end

最后调用库函数检测是否正确并绘图:

% 用toolbox的medfilt2函数
median_lib = medfilt2(noise_image, [3,3]);

% 绘制图像
figure
subplot(2,2,1), imshow(image);
title("原图像");
subplot(2,2,2), imshow(noise_image);
title("椒盐噪声图像");
subplot(2,2,3), imshow(median_image);
title("中值滤波图像");
subplot(2,2,4), imshow(median_lib);
title("matlab结果图像");

原图像加上椒盐噪声后,背景变成了很多白色和黑色高亮或黑色的斑点。

经过中值滤波和调库的中值滤波后的结果大致相符合,可能是因为padding或者别的原因导致有一些细微的差别。则实验获得了成功,代码编写正确。

http://www.dtcms.com/a/122263.html

相关文章:

  • 【回眸】Linux 内核 (十六) 之 多线程编程 下
  • 基于Python的心衰疾病数据可视化分析系统
  • 【论文精读】Multi-scale Neighbourhood Feature Interaction Network
  • JavaScript Hook JSON.stringify和JSON.parse:逆向与修改实战指南
  • AWS弹性容器服务(AWS Elastic Container Service,ECS)概述
  • js中this指向问题
  • deque容器
  • 排序算法(快速排序,选择排序......)【泪光2929】
  • FPGA_modelsim错误总结
  • 一、简单的 Django 服务
  • 软考 系统架构设计师系列知识点 —— 设计模式之工厂模式
  • 518. Coin Change II
  • React中使用dnd-kit实现拖拽排序
  • ASP Response
  • 分布式存储系统Ceph
  • 微信小程序:动态表格实现,表头单元格数据完全从data中获取,宽度自定义,自定义文本框,行勾选,样式效果,横向滚动表格(解决背景色不足的问题)等
  • TCP重传率高与传输延迟问题
  • 【scikit-learn基础】--『数据加载』之外部数据集
  • pip install pytrec_eval失败的解决方案
  • 自动变为 VIP 文章
  • python基础语法11-文件读写
  • 程序代码篇---时间复杂度空间复杂度
  • 初识Linux:常见指令与权限的理解,以及相关衍生知识
  • Jetpack Compose 状态保存机制全面解析:让UI状态持久化
  • JavaWeb遇到的问题汇总
  • 2025 销售困局:AI 强势入局,传统模式如何突围?
  • 解决 ECharts 图表无数据显示问题
  • 网工毕业设计项目选题推荐
  • Redis Java 客户端 之 SpringDataRedis
  • Diffusion Policy Visuomotor Policy Learning via Action Diffusion官方项目解读(二)(5)