• 第一步当然是读取图像了: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. 共读《redis设计与实现》-单机(一)

    上一章我们讲了 redis 基本类型的数据结构 和 对象系统 ,这篇来说一下单机redis 的知识点. 一.数据库 一个数据库在redis中就有一个结构体,而数据库的结构体是由redisServer这 ...

  2. 使用vscode编辑markdown文件(可粘贴截图)

    使用markdown粘贴截图时,操作步骤比较多: 1)截取图片: 2)将图片存在特定位置: 3)记住图片路径,在markdown文件中编写代码: 4)预览效果: 而word之类的文档编辑器,只需要截图 ...

  3. Android C/C++层hook和java层hook原理以及比较

    作者:Denny Qiao(乔喜铭),云智慧/架构师. 云智慧集团成立于2009年,是全栈智能业务运维解决方案服务商.经过多年自主研发,公司形成了从IT运维.电力运维到IoT运维的产业布局,覆盖ITO ...

  4. 真实本人亲测Elasticsearch未授权访问漏洞——利用及修复【踩坑指南到脱坑!】

    如要转载请注明出处谢谢: https://www.cnblogs.com/vitalemontea/p/16105490.html 1.前言 某天"发现"了个漏洞,咳咳,原本以为这 ...

  5. [AcWing 822] 走方格

    点击查看代码 #include<iostream> using namespace std; int n, m, ans = 0; void dfs(int x, int y) { if ...

  6. 网络协议OSI模型-TCP/IP-三次握手

    OSI模型 在制定计算机网络标准方面,起着重大作用的两大国际组织是:国际电信联盟电信标准化部门,与国际 标准组织(ISO),虽然它们工作领域不同,但随着科学技术的发展,通信与信息处理之间的界限开始 变 ...

  7. 3.yum学习笔记

    一.yum介绍 将所有的rpm软件包放到指定服务器上,当进行yum在线安装时,可以自动解决依赖性问题. yum配置文件常位于/etc/yum.repo.d 目录下 [root@aaa251 ~]# c ...

  8. 原来 Linux 日志文件系统是这样工作的~

    关注「开源Linux」,选择"设为星标" 回复「学习」,有我为您特别筛选的学习资料~ 作者:Linux Performance 链接:http://linuxperf.com/?p ...

  9. SpringBoot整合MybatisPlus基本的增删改查,保姆级教程

    概述 MybatisPlus是国产的第三方插件, 它封装了许多常用的CURDapi,免去了我们写mapper.xml的重复劳动,这里介绍了基本的整合SpringBoot和基础用法. 引入依赖 在项目中 ...

  10. 【PyHacker编写指南】打造URL批量采集器

    这节课是巡安似海PyHacker编写指南的<打造URL批量采集器> 喜欢用Python写脚本的小伙伴可以跟着一起写一写呀. 编写环境:Python2.x 00x1: 需要用到的模块如下: ...