• 第一步当然是读取图像了:read_image (Image, 'C:/Users/HJ/Desktop/test_image/b.jpg')

  • 第二步:二值化。二值化。因为我这里的物体是黑色的,所以用binary_threshold来二值化的时候参数选择的‘dark’,如果特征是白色的话可以把dark改为light,效果如下:

  • 第三步:将区域打散,然后根据过滤条件来进行赛选,我这里是通过面积来进行筛选 。过滤条件在这里只用了一个,也可以使用多个过滤条件来进行过滤。

connection (Region, ConnectedRegions)

select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 400000, 9900000)

​编辑​编辑

  • 第四步:筛选完之后就只剩下想要的区域了,然后寻找区域的最小外接矩形。

smallest_rectangle2 (SelectedRegions, Row, Column, Phi, Lenghts1, Lenghts2)
           返回的Row,Column是区域特征的中心点坐标,Lenghts1是物体区域的长边的一半,Lenghts2是物体区域的短边的一半,Lenghts1>Lenghts2恒成立。Phi是x轴(水平)与长边的夹角的弧度,

它的值在(-π/2, π/2), 要将phi换成角度的话只用angle := -180/π  * phi就好了

  • 第五步:因为在实际场景中,拍出来的图片位置会有些许差异,所以我们需要得到一个统一的输出,也就是输出的图片中物体的位置差异不大。所以就需要经过旋转和裁切来进行处理。

rotate_image(Image, ImageRotate, angle, 'constant')

在halcon中rotate_image是按逆时针方向进行旋转,而且旋转后的图片大小不变,但内容可能会有缺失。并且物体的中心在原图的位置和在旋转之后图片上的位置还会有差异。

​编辑

为了解决使用rotate_image进行旋转产生的问题,可以所以建议使用旋转矩阵来进行旋转。具体参数解释在代码里

hom_mat2d_identity(HomMat2DIdentity)

hom_mat2d_rotate(HomMat2DIdentity, rad(angle), Row, Column, HomMat2DRotate)

affine_trans_image(Image, ImageAffineTrans, HomMat2DRotate, 'constant', 'false')

​编辑

  • 第六步:裁剪出想要的区域

crop_part(ImageAffineTrans, ImagePart, Row-Lenghts2, Column-Lenghts1, 2*Lenghts1, 2*Lenghts2)

​编辑

注意事项:

  1. 在旋转的时候我们的角度是angle:=180/π  * phi,旋转之后物体的长边与X轴平行(也就是本子平着)。如果想要本子竖起来就需要令angle := -(ratio*Phi+90)这样子旋转之后本子就竖起来
  2. 在使用crop_part这个函数对图像进行裁切时,如果长边与X轴平行则Row-Length2,Column-Length1。保存的图像的长宽分别为2*Lenghts1, 2*Lenghts2
  3. 如果短边与X轴平行则Row-Length1,Column-Length2。保存的图像的长宽分别为2*Lenghts2, 2*Lenghts1
  4. 使用旋转矩阵旋转之后物体的中心其实是发生了变化的,并且length1可能会大于row和column,所以在crop_part的时候需要注意输入左上角的坐标
  5. 其实由于旋转之后物体中心发生了变化,我更倾向于对旋转之后的图片再重新二值化寻找轮廓,这样子物体中心就是正常的了。然后再进行裁切图片

总体代码:

read_image (Image, 'C:/Users/HJ/Desktop/save_image/angle_60.png')
*自适应二值化,当寻找的物体为偏黑时使用dark, 偏白时使用lightbinary_threshold(Image, Region, 'max_separability', 'light', UsedThreshold)*将区域打散connection (Region, ConnectedRegions)*通过面积来筛选区域select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 400000, 9900000)*寻找区域的最小外接矩形,返回的Phi是弧度,在(-π/2,π/2)之间*Row,Column是中心点的坐标,length1是物体的长边的一半, length2是物体短边的一半smallest_rectangle2 (SelectedRegions, Row, Column, Phi, Lenghts1, Lenghts2)
*角度换算,将弧度换算成角度ratio := 90.045/1.5708angle := ratio*Phi*创建vertical来控制旋转是垂直还是水平, 1表示长边与x轴平行, 0表示短边与x轴平行vertical := 0*创建旋转矩阵hom_mat2d_identity(HomMat2DIdentity)if (vertical == 1)  *旋转使用的是弧度,所以需要用rad将角度换成弧度, row, column是旋转中心  hom_mat2d_rotate(HomMat2DIdentity, rad(90-angle), Row, Column, HomMat2DRotate)  *旋转图片,false的时候图像大小不发生改变,true的时候图像大小会变化,使用旋转矩阵旋转之后物体的中心其实是发生了变化的,  *所以在截取物体的时候其实还要在重新寻找一些物体在旋转之后的图片上的中心位置  affine_trans_image(Image, ImageAffineTrans, HomMat2DRotate, 'constant', 'true')  *裁切图片,当长边与x轴平行时,Row-Lenghts2, Column-Lenghts2, 2*Lenghts1, 2*Lenghts2  *当短边与x轴平行时,Row-Lenghts1, Column-Lenghts2, 2*Lenghts2, 2*Lenghts1
  *Row-Lenghts1, Column-Lenghts2是左上角的坐标,2*Lenghts2, 2*Lenghts1是截取的场合宽  crop_part(ImageAffineTrans, ImagePart, Row-Lenghts1, Column-Lenghts2, 2*Lenghts2, 2*Lenghts1)else   hom_mat2d_rotate(HomMat2DIdentity, rad(-angle), Row, Column, HomMat2DRotate)   affine_trans_image(Image, ImageAffineTrans, HomMat2DRotate, 'constant', 'true')   crop_part(ImageAffineTrans, ImagePart, Row-Lenghts2, Column-Lenghts1, 2*Lenghts1, 2*Lenghts2)endif
 
 

halcon 基础总结(一)裁切图片并旋转图像的更多相关文章

  1. halcon基础应用和方法经验分享

    halcon基础应用和方法经验分享 一.Halcon软件 的安装 安装一直点下一步就好了,这个过程很简单,就不讲了 二.Halcon软件license安装 Halcon是商业视觉软件,是需要收费的,但 ...

  2. halcon基础数据类型

    halcon基础数据类型 使用变量不需定义 等号       := 不等号    # 字符串赋值  str:='sdff' 等于比较符         if(q=0) 与       if(a< ...

  3. canvas压缩、裁切图片和格式转换的方法

    按照大小压缩图片,或者按照特定分辨率裁切图片,转为blob数据.自动处理ios中可能存在的照片偏差90°问题. 例如,获取300*300大小的头像,实现以下效果: 使用方式: <!-- 引入js ...

  4. halcon保存带有region的图片算子

    显示带区域的图片除了可以用dev_display挨个显示外再截图,还可以通过一个算子来实现这一功能 这个算子是:dump_window_image.(其实就是截图) 这个算子的意思是把WindowHa ...

  5. vue 实现 裁切图片 同时有放大、缩小、旋转功能

    实现效果: 裁切指定区域内的图片 旋转图片 放大图片 输出bolb 格式数据 提供给 formData 对象 效果图 大概原理: 利用h5 FileReader 对象, 获取 <input ty ...

  6. halcon基础算子介绍(窗口创建,算子运行时长,是否启用更新函数)

    前言 halcon有有大约1500个算子,我总结一些简单大家用得到的算子,比如创建窗口的方式有3种,接下来结束这方式,及其异同点等! 1.窗口创建的三种方式 1.1使用dev_open_window算 ...

  7. nodeJS基础08:读取图片

    1.读取图片 //server.js var http = require("http"); var readImage = require("./readImage&q ...

  8. [C#基础实例]指定地址解析图片并下载

    需求:查找页面图片并下载至本地: 实现: 首先:读取通过网络html内容,并用正则表达式查找图片地下. 其次:使用WebRequest.Create创建图片请求. 最后:把获取图片网络流数据通过Fil ...

  9. HALCON基础知识

    HALCON 1. 语法范式 Syntax Style 1.1. 基本格式 1.1.1. 算子格式 算子(输入图像参数:输出图像参数:输入控制参数:输出控制参数) 其中四个参数任意一个可以为空 e.g ...

随机推荐

  1. javascript中的宏任务和微任务(一)

    一.宏任务和微任务有哪些 宏任务:setTimeout,setInterval,ajax,dom,宏任务是由浏览器提供的 微任务:promise,async/await,微任务是由es6提供的 二.微 ...

  2. js call与bind和apply的区别

    介绍 在JS中,这三者都是用来改变函数的this对象的指向的,他们有什么样的区别呢. 在说区别之前还是先总结一下三者的相似之处: 1.都是用来改变函数的this对象的指向的. 2.第一个参数都是thi ...

  3. 新华三Gen10服务器ILO 5 安装中文语言包

    ILO 5 安装中文语言包 在官网下载语言包文件,并解压 选择firmware&OS software,点击右侧的update firmware 选择本地文件,浏览到语言包里面的lpk文件,点 ...

  4. Java面试题资料合集

    Java面试题资料合集 2021年最新版--Java+最常见的+200++面试题汇总+答案总结汇总.pdf BIO,NIO,AIO,Netty面试题 35道.pdf Dubbo面试题 47道.pdf ...

  5. HCNP Routing&Switching之Super VLAN

    前文我们了解了VLAN隔离技术MUX VLAN相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/16196936.html:今天我们来聊一聊VLAN优化S ...

  6. CSS预编译器

    零.CSS预编译器 CSS预处理器是指对生成CSS前的某一语法的处理.CSS预处理器用一种专门的编程语言,进行Web页面样式设计,然后再编译成正常的CSS文件,供项目使用 CSS预处理器为CSS增加一 ...

  7. 一个比 Nginx 功能更强大的 Web 服务器

    公众号关注 「开源Linux」 回复「学习」,有我为您特别筛选的学习资料~ Caddy 简介 Caddy 是一个 Go 编写的 Web 服务器,类似于 Nginx,Caddy 提供了更加强大的功能,随 ...

  8. MySQL基准测试工具

    一.基准测试 基准测试(benchmark)是针对系统设计的一种压力测试. 基准测试是简化了的压力测试. 1.1 常见指标 TPS QPS 响应时间 并发量 1.2 收集与分析数据脚本 收集数据的sh ...

  9. 141. Linked List Cycle - LeetCode

    Question 141. Linked List Cycle Solution 题目大意:给一个链表,判断是否存在循环,最好不要使用额外空间 思路:定义一个假节点fakeNext,遍历这个链表,判断 ...

  10. 89. Gray Code - LeetCode

    Question 89. Gray Code Solution 思路: n = 0 0 n = 1 0 1 n = 2 00 01 10 11 n = 3 000 001 010 011 100 10 ...