我在Gitee上建了个仓库,会将学习书本的时候打的一些代码上传上去,笔记中所有代码都在仓库里,初学的朋友可以一起交流哦!地址(Gitee)


第五章 图像运算


图像的代数运算

加法运算

以平均处理的方法将图像加法运用到图像的去噪中,先将噪声\(\eta(x,y)\)加入原始图像\(f(x,y)\)中,即$ g(x,y)=f(x,y)+\eta(x,y) $

然后重复操作数次,将得到的\(K\)张不同的噪声图取平均值,得到平均值图像\(\overline{g}(x,y)\),即

\[\overline{g}(x,y)=\frac{1}{K}\sum_{i=1}^k{g_i(x,y)} \\
E\{{\overline{g}(x,y)}\}=f(x,y) \\
\\\]

用到的算子

add_image(Image1, Image2 : ImageResult : Mult, Add : )

作用:将两幅图像相加

新图像ImageResult的灰度值计算如下

\[g'=(g1+g2)*Mult+Add
\]

图像加法的平均处理程序如下

dev_close_window ()
read_image (Image, '噪点图')
get_image_size (Image, Width, Height)
dev_open_window (0, 0, Width*1.5, Height*1.5, 'black', WindowHandle)
dev_display (Image)
rgb1_to_gray (Image, GrayImage)
* 将数据类型转换为实数
convert_image_type (GrayImage, ImageConverted, 'real')
* 复制图片,保护原图
copy_image (ImageConverted, DupImage)
* 生成空图像数组
gen_empty_obj (ImageNoiseArray)
* 循环生成白噪声图存入数组
for i:=1 to 10 by 1
add_noise_white (DupImage, ImageNoise, 60)
concat_obj (ImageNoiseArray, ImageNoise, ImageNoiseArray)
endfor
* 叠加图像
for i:=2 to 10 by 1
if(i=2)
* 选择前两张图片相加
select_obj (ImageNoiseArray, ObjectSelected, 1)
select_obj (ImageNoiseArray, ObjectSelected1, 2)
add_image (ObjectSelected, ObjectSelected1, ImageResult, 1, 0)
else
* 循环叠加图片
select_obj (ImageNoiseArray, ObjectSelected2, i)
add_image (ObjectSelected2, ImageResult, ImageResult, 1, 0)
endif
endfor * 对生成的图片求平均值
scale_image (ImageResult, ImageScaled, 0.1, 10)

运行结果感觉不是很好

图像合成的程序如下

read_image (Image, 'patras')
read_image (Image1, 'brycecanyon1')
Width:=720
Height:=480
* 裁剪两张图片得到形同大小区域
crop_part (Image, ImagePart, 0, 0, Width, Height)
crop_part (Image1, ImagePart1, 0, 0, Width, Height)
dev_close_window ()
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
dev_display (ImagePart)
* 设置字体
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
disp_message (WindowHandle, 'Image', 'window', 20, 20, 'black', 'true')
stop ()
dev_display (ImagePart1)
disp_message (WindowHandle, 'Image1', 'window', 20, 20, 'black', 'true')
stop ()
add_image (ImagePart, ImagePart1, ImageResult, 0.5, 0)
dev_display (ImageResult)
disp_message (WindowHandle, 'Composite Image', 'window', 20, 20, 'black', 'true')

运行结果如下图


图像减法

对两幅图像的差异可以用图像减法检测出,HLACON中计算图像差异通常是计算两幅图像的对应像素点的差异。

HLACON实现图像减法的算子如下

sub_image(ImageMinuend, ImageSubtrahend : ImageSub : Mult, Add : )

作用:图像相减,ImageMinuend-ImageSubtrahend

得到的ImageSub灰度值g'表达式如下

\[g'=(g1-g2)*Mult+Add
\]

图像减法程序运行结果如下

图像乘法

图像乘法可以用来将图像中所需的部分提取出来,就是将掩模图和待处理图片相乘(掩模图和待处理图像必须是同一通道的图像)

HALCON中实现图像乘法的算子如下

mult_image(Image1, Image2 : ImageResult : Mult, Add : )

作用:图像相乘

得到的图像ImageResult的灰度值g'表达式如下

\[g'=g1*g2*Mult+Add
\]

图像乘法程序如下

dev_close_window ()
read_image (Image, 'fabrik')
get_image_size (Image, Width, Height)
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
dev_display (Image)
read_image (Image1, '掩模')
* 将图像转为单通道
rgb1_to_gray (Image1, GrayImage)
* 图像相乘
mult_image (Image, GrayImage, ImageResult, 0.005, 0)

程序运行结果如下图

图像除法

图像除法可以用于校正成像设备的非线性影响,除法也可以检测图像的变化,但是除法操作给出的是相应像素间的变化比率,而不是像素的绝对差异,因此图像除法也被称为比率变换

HALCON中实现图像除法的算子如下

div_image(Image1, Image2 : ImageResult : Mult, Add : )

作用:图像相除

得到的图像ImageResult的灰度值g'表达式如下

\[g'=g1/g2*Mult+Add
\]

图像除法程序如下

dev_close_window ()
dev_update_off ()
read_image (Image, 'autobahn/scene_00')
* 创建灰度斜坡图
gen_image_gray_ramp (ImageGrayRamp, 0.2, 0.2, 128, 256, 256, 512, 512)
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
* 设置字体
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_display (Image)
disp_message (WindowHandle, 'Origin Image', 'window', 12, 12, 'black', 'true')
stop ()
dev_display (ImageGrayRamp)
disp_message (WindowHandle, 'Gray Value Image', 'window', 12, 12, 'black', 'true')
stop ()
* 图像相除
div_image (Image, ImageGrayRamp, ImageResult, 255, 0)
dev_display (ImageResult)
disp_message (WindowHandle, 'Resulting Image', 'window', 12, 12, 'black', 'true')

程序运行结果如下图

图像逻辑运算(位操作)

图像位操作的程序如下

read_image (Image, 'fabrik')
read_image (Image1, '掩模')
read_image (Image2, '1.bmp')
read_image (Image3, '2.bmp')
rgb1_to_gray (Image1, GrayImage)
* 按位与
bit_and (Image, GrayImage, ImageAnd)
* 按位或
bit_or (Image, GrayImage, ImageOr)
* 按位异或
bit_xor (Image2, Image3, ImageXor)
* 按位取反
bit_not (Image2, ImageNot)
* 按位左移
bit_lshift (Image3, ImageLShift, 3)
* 按位右移
bit_rshift (Image3, ImageRShift, 3)

程序运行效果如下图


图像的几何变换

图像几何变换的一般表达式

  1. 点变换

    图像处理其实就是针对图像的每个像素点的处理,点处理分为几种,有比例变换、原点变换、绕x/y/x=y轴翻转、剪移等

  2. 直线变换——两个点的变换

    判断两条直线平行与否只需要判断直线上的两个点即可

  3. 单位正方形变换

    在单位正方形和平行四边形之间建立映射关系,达到互相转换

仿射变换

仿射变换可以做到对图像上的物体进行平移和角度修正,仿射变换的一般表达式为

\[\begin{bmatrix}u \\ \upsilon\end{bmatrix}=A\begin{bmatrix}x \\ y \\1 \end{bmatrix}=\begin{bmatrix}a_2 & a_1 & a_0 \\ b_2 & b_1 & b_0 \end{bmatrix}\begin{bmatrix}x \\ y \\1 \end{bmatrix}
\]

HLAOCN中做仿射变换需要先定义变换矩阵,然后对矩阵进行平移、缩放、旋转等操作后在应用矩阵到图像或区域上,有关算子列举一些在下面

hom_mat2d_identity( : : : HomMat2DIdentity)

作用:定义仿射变换矩阵

hom_mat2d_translate( : : HomMat2D, Tx, Ty : HomMat2DTranslate)

作用:在2D齐次仿射变换中增加平移变换

hom_mat2d_scale( : : HomMat2D, Sx, Sy, Px, Py : HomMat2DScale)

作用:在2D齐次仿射变换中增加缩放变换

hom_mat2d_rotate( : : HomMat2D, Phi, Px, Py : HomMat2DRotate)

作用:在2D齐次仿射变换中增加旋转变换

affine_trans_region(Region : RegionAffineTrans : HomMat2D, Interpolate : )

作用:针对区域做仿射变换

affine_trans_image(Image : ImageAffinTrans : HomMat2D, Interpolation, AdaptImageSize : )

作用:针对图像做仿射变换

仿射变换的程序如下

dev_close_window ()
dev_open_window (0, 0, 512, 512, 'white', WindowHandle)
dev_set_color ('red')
gen_rectangle1 (Rectangle, 20, 20, 100, 100)
dev_display (Rectangle)
* 定义仿射变换矩阵
hom_mat2d_identity (HomMat2DIdentity)
* 增加平移变换量
hom_mat2d_translate (HomMat2DIdentity, 0, 120, HomMat2DTranslate)
* 应用仿射变换
affine_trans_region (Rectangle, RegionAffineTrans, HomMat2DTranslate, 'nearest_neighbor')
dev_display (RegionAffineTrans)
* 增加缩放变换量
hom_mat2d_scale (HomMat2DTranslate, 1.2, 1.2, 16, 16, HomMat2DScale)
* 应用仿射变换
affine_trans_region (RegionAffineTrans, RegionAffineTrans1, HomMat2DScale, 'nearest_neighbor')
dev_display (RegionAffineTrans1)
* 增加旋转变化量
hom_mat2d_rotate (HomMat2DTranslate, 0.6, 256,256, HomMat2DRotate)
* 偏移一下位置
hom_mat2d_translate (HomMat2DRotate, 150, 50, HomMat2DTranslate1)
* 适当变大
hom_mat2d_scale (HomMat2DTranslate1, 2, 2, 64, 64, HomMat2DScale1)
* 应用仿射变换
affine_trans_region (RegionAffineTrans, RegionAffineTrans2, HomMat2DScale1, 'nearest_neighbor')
dev_display (RegionAffineTrans2)

程序运行结果如下图

投影变换

投影变换也是一种平面映射,可以称为特殊的投影变换,它的正变换和逆变换都是单值的,而且可以保证任意方向上的直线经过变换还能保持直线

投影变换的算子如下

hom_vector_to_proj_hom_mat2d( : : Px, Py, Pw, Qx, Qy, Qw, Method : HomMat2D)

作用:确定投影变换矩阵HomMat2D指定矩阵的四个点,从而确定矩阵

灰度插值

  1. 最近邻插值法

最近邻插值法也称为零阶插值,即令变换后像素的灰度值等于距离它最近的输入像素的灰度值。这种方法造成的空间偏移误差为\(\frac{1}{\sqrt{2}}\)像素

  1. 双线性插值法

双线性插值法也称为一阶插值,这种方法是沿着图像矩阵的每一行(列)进行插值,然后对插值后得到的矩阵再沿着行(列)方向进行线性插值

这种方法在对相邻4个像素点的时候得到的表面在邻域是吻合的,但是斜率是不同的,这样会让图像的细节产生退化

  1. 卷积插值法

卷积插值法在输入图像的两行列之间插入零值,然后通过低通模版滤波得到插值后的图像

灰度插值法程序如下

dev_update_window ('off')
dev_update_var ('off')
dev_update_time ('off')
dev_update_pc ('off')
dev_set_color ('red')
read_image (Image, 'forest_road')
dev_display (Image)
threshold (Image, Regions, 160, 218)
* 开运算
opening_circle (Regions, RegionOpening, 9)
dev_display (RegionOpening)
disp_message (3600,'Ready to rotate', 'window', 12, 12, 'black', 'true')
stop ()
* 定义仿射变换矩阵
hom_mat2d_identity (HomMat2DIdentity)
Scale:=1 //缩放比例
*循环旋转和缩放
for Phi := 0 to 360 by 1
hom_mat2d_rotate (HomMat2DIdentity, rad(Phi), 256, 256, HomMat2DRotate)
hom_mat2d_scale (HomMat2DRotate, Scale, Scale, 256, 256, HomMat2DScale)
* 对图像和区域应用仿射变换
affine_trans_image (Image, ImageAffinTrans, HomMat2DScale, 'nearest_neighbor', 'false')
affine_trans_region (RegionOpening, RegionAffineTrans, HomMat2DScale, 'nearest_neighbor')
dev_display (ImageAffinTrans)
dev_display (RegionAffineTrans)
* 更改缩放比例
Scale:=Scale/1.005
endfor
stop ()
*循环旋转和缩放
for Phi := 0 to 360 by 1
hom_mat2d_rotate (HomMat2DIdentity, rad(-Phi), 256, 256, HomMat2DRotate)
hom_mat2d_scale (HomMat2DRotate, Scale, Scale, 256, 256, HomMat2DScale)
* 对图像和区域应用仿射变换
affine_trans_image (Image, ImageAffinTrans, HomMat2DScale, 'nearest_neighbor', 'false')
affine_trans_region (RegionOpening, RegionAffineTrans, HomMat2DScale, 'nearest_neighbor')
dev_display (ImageAffinTrans)
dev_display (RegionAffineTrans)
* 更改缩放比例
Scale:=Scale*1.005
endfor
disp_message (3600, '好玩吧', 'window', 12, 12, 'black', 'true')
stop ()
dev_update_window ('on')
dev_update_var ('on')
dev_update_time ('on')
dev_update_pc ('on')

程序运行结果如下图


图像校正

图像校正非常有用,在"扫描全能王"之类的扫描软件里面经常用到,可以将不是正对着屏幕的文件变成正常的矩形显示出来,在HLACON中也可以实现这种效果,只是我现在功力还不足,只能做到手动标注矩阵点

图像校正程序运行结果如下图

第五章的笔记就到这里啦,如果你一路看到了这里,帮我点个赞吧O(∩_∩)O~,祝大家学习能有所收获!

《HALCON数字图像处理》第五章笔记的更多相关文章

  1. 《HALCON数字图像处理》第一、二章笔记

    目录 第一章 绪论 1.1 图像和图像处理 1.1.1 图像 1.1.2 数字图像 1.1.3 图像处理及其发展过程 1.2 数字图像处理的步骤和方法 1.3 数字图像处理系统的硬件组成 1.4 数字 ...

  2. 数字图像处理(MATLAB版)学习笔记(2)——第2章 灰度变换与空间滤波

    0.小叙闲言 1.本章整体结构 2.书中例子 例2.1 主要是使用函数imadjust,来熟悉一下灰度处理,体验一把 >> imread('myimage.jpg'); >> ...

  3. 数字图像处理(MATLAB版)学习笔记(1)——第1章 绪言

    0.下定决心 当当入手数字图像处理一本,从此开此正式跨入数字图像处理大门.以前虽然多多少少接触过这些东西,也做过一些相关的事情,但感觉都不够系统,也不够专业,从今天开始,一步一步地学习下去,相信会有成 ...

  4. 《APUE》第五章笔记

    第五章具体介绍了标准I/O库的各种细节,要是一一列出来,有费精力且可能列不全,故只讲平常多用到的.标准输入输出是由一大批函数组成的. 要记住,标准输入输出是有缓冲的,就是当缓冲区的数据满了的时候,才会 ...

  5. 【数字图像处理】五.MFC图像点运算之灰度线性变化、灰度非线性变化、阈值化和均衡化处理具体解释

    本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程<数字图像处理>及课件进行解说.主要通过MFC单文档视图实现显示BMP图片点运算处理.包含图像灰度线性变换 ...

  6. 《HALCON数字图像处理》第四章笔记

    目录 第四章 HALCON数据结构 HALCON Image图像 图像通道 HALCON Region区域 Region的初步介绍 Region的点与线 Region的行程 Region的区域特征 H ...

  7. 《HALCON数字图像处理》第三章笔记

    目录 第三章 HALCON图像处理基础 HALCON控制语句 HALCON算子 HALCON图像处理入门 HALCON图像读取 HALCON图像显示 图形窗口 图像显示 显示文字 HALCON图像转换 ...

  8. 《HALCON数字图像处理》第六章笔记

    目录 第六章 图像增强 图像增强的概念和分类 灰度变换 直方图处理 图像的平滑 图像的锐化 图像的彩色增强 我在Gitee上建了个仓库,会将学习书本的时候打的一些代码上传上去,笔记中所有代码都在仓库里 ...

  9. 鸟哥的Linux私房菜:基础学习篇 —— 第五章笔记

    1.Linux一般将文件可存取的身份分为三个类 别,分别是 owner/group/others,且三种身份各有 read/write/execute 等权限.其中 root 的权限最高. 2.在我们 ...

随机推荐

  1. 微信小程序插件组件-Taro UI

    微信小程序组件使用以下官网查看 ↓  ↓  ↓ https://taro-ui.jd.com/#/docs/fab

  2. 跳转到下一页面时,必须先勾选阅读xx须知/协议才可跳转功能

    当跳转到新的html页面时,先判断checkbox是否选中,选中-->跳转到新页面:未选中--弹出提示消息(请先同意须知) HTML: 1 <div class="choose& ...

  3. JWT&RSA实现单点登录(详细介绍)

    今天给大家讲一下基于JWT&RSA的单点登录(Single Sign On,简称SSO)解决方案 概念 首先要了解几个概念 单点登录(Single Sign On) JWT RSA 背景 为什 ...

  4. What is ACPI

    What is ACPI, OnNow, and PCI Power Management? Microsoft began an initiative called OnNow to shorten ...

  5. 进程的概念及multiprocess模块的使用

    一.进程 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机结构中,进程是程序的基本执行实体:在 ...

  6. LinkedList实现

    LinkedList源码实现: public class LinkedList<E> { private class Node{ public E e; public Node next; ...

  7. windows安装rabbitmq踩坑实录

    最近学习springcloud消息总线需要用到rabbitmq,然后安装的时候踩了一些坑,记录如下: 首先安装rabbitmq之前需要先安装erlang,因为rabbitmq服务端使用erlang写的 ...

  8. Java之万年历

    @(文章目录) 二.Java之万年历 2.1 要求 输入年份: 输入月份: 输出某年某月的日历. 2.2 思路 实现从控制台接收年和月,判断是否是闰年(判断是否是闰年:能被4整除但不能被100整除:或 ...

  9. 如何为我的VUE项目编写高效的单元测试--Jest

    Unit Testing(单元测试)--Jest 一个完整的测试程序通常由几种不同的测试组合而成,比如end to end(E2E)测试,有时还包括整体测试.简要测试和单元测试.这里要介绍的是Vue中 ...

  10. Java语言学习day38--8月13日

    ###11哈希表的数据结构 A:哈希表的数据结构:(参见图解) 加载因子:表中填入的记录数/哈希表的长度 例如: 加载因子是0.75 代表: 数组中的16个位置,其中存入16*0.75=12个元素 如 ...