detect_brochure_pages.hdev

 
*这个例子主要描述了从图片库中寻找有相应页面的那一页
*第一步中,不同的纸张页面用来做训练,最后创建好model
*第二步,在未知的页面图片中来搜索,找出正确的那一页
dev_update_off()
dev_close_window()
read_image(Image, '...')
get_image_size(Image, Width, Height)
...
clear_all_descriptor_models()
把存储器中所有的descriptor模型清除,释放空间
*定义变量:
ModelIDs :=[]
ModelsFound :=0
NumPoints :=[]
NumModels:= 3
TotalTime :=0
 
*创建用来观察的region
RowRoi :=[10, 10, Height-10, Height-10]
ColRoi := [10, Width-10, Width-10, 10]
gen_rectangle1(Rectangle, 10, 10, Height-10, Width-10)
disp....
stop()
 
(1)第一步,为每个page创建一个描述模型descriptor model
for Index :=1 to NumModels by 1
read_image(Image, ' brochure/brochure_page_'+Index$'.2')
rgb1_to_gray(Image, ImageGray)
get_image_size(ImageGray,Width, Height)
reduce_domain(ImageGray, Rectangle, ImageReduced)
disp.......
 
*使用默认参数创建描述模型descriptor model,尺度参数需要自定义,这里为了加速搜索过*程,兴趣点检测方式使用harris binomial point detector
count_seconds(Second1)
create_uncalib_descriptor_model(ImageReduced, 'harris_binomal',[], [], ['min_rot', 'max_rot', 'min_scale', 'max_scale' ],[-90, 90 , 0.2, 1.1], 42, ModelID)
创建一个描述模型descriptor model来描述一张图片,和deformable model区别是没有用图面金字塔来进行整体匹配,而是针对一个个兴趣点进行匹配,所以创建描述模型的过程主要有两步,第一是利用参数中DetectorType给定的检测方式来检测出兴趣点,第二部是根据兴趣点的位置以及其周边点的关系,灰度值来建立descriptor描述器,用来描述相应兴趣点,创建方式根据DescriptorType种类不同而有所区别。(注意这里是uncalib属性,代表不需要使用有矫正标定功能的相机)
seed参数生成随机数,用来使建立的描述器具有随机性,默认42.
在创建了模型之后,可以使用find_uncalib_descriptor_model来搜索出包括平面的和立体的仿射变换后的模型。返回转换矩阵。/*
 
count_seconds(Second2)
TotalTime :=TotalTime+(Second2-Second1)
disp......
 
*为了能够正确的映射模型,在进行搜索前必须先标定一个转换的参照点 ,这里描述模型*descriptor model的中心点为参照点
set_descriptor_model_orgin(ModelID, -Height/2, -Width/2)
*/set_descriptor_model_origin( : : ModelID, Row, Column : )
为descriptor 模型设置原点(参照点)
描述:参照点 通常和创建模型时候(create_uncalib_descriptor_model, or create_calib_descriptor_model)使用的region输入的重力中心点相关,参数的设定即表示相对于重力中心点的位移,eg:一个原点是(-20,-10)表示这个原点在重力中心点的左上角。
         在设定了参照点之后,使用find_uncalib_descriptor_model and find_calib_descriptor_model来搜索模型的形态和转换信息
注意:这里设置的参照点是属于模型的一部分,是模型的一个属性/*ModelIDs :=[ModelIDs, ModelID] 把生成的modelID存入数组/*
*存储生成的模型中的兴趣点 get_descriptor_model_points(ModelID, 'model', 'all', Row_D, Col_D) */get_descriptor_model_points( : : ModelID, Set, Subset : Row, Column) Set可以控制是取出模型中的兴趣点还是上一次搜索的图片中的兴趣点,subset表示取出几个点,默认为‘all'(这里用all也会比较慢,可以考虑选取其他数值),后两个参数是输出,保存了这些点的信息。
Subset : 每个如果是搜索的话,每个正确的匹配的兴趣点是所有兴趣点的一个子集/*
NumPoints :=[NumPoints, |Row_D|] endfor   到此,模型的创建工作结束
(2)第二步, 搜寻工作        *因为图片大小的改变,应该先重新初始化窗体      read_image(Image, 'bro.....01')
dev_resize_window_fit_image(Image, 0,0,-1,-1)
set_display_frnt
 
*再循环中搜索模型(遍历所有图片)
for Index1: = 1 to 12 by 1           一共有12张图片
OutputString: =[]
NumMsgs:=0
ModelsFound :=0
TotalTime:=0
 
read_image(Image, 'brochure/brochure_'+Index1$'.2')
rgb1_to_gray(Image, ImageGray)
display image and message......
*搜索, 在一张图片中逐个的搜索所有模型
for Index2 := 0 to |ModelIDs| -1 by 1
count_seconds(Seconds1)
find_uncalib_descriptor_model(ImageGray, ModelIDs[Index2], 'threshold', 800,  ['min_score_descr', 'guided_matching'], [0.003, 'on'], 0.25, 1, 'num_points', HomMat2D, Score)
find_uncalib_descriptor_model(Image : : ModelID, DetectorParamName, DetectorParamValue, DescriptorParamName, DescriptorParamValue, MinScore, NumMatches, ScoreType : HomMat2D, Score(最后两个是操作的输出,其他均为输入))
*/描述:寻找描述模型,DetectorParamNameDescriptorParamName应该与创建模型时候相同。
MinScore:当Score超过MinScore时候,这个匹配才被接受。
对于每一个接受的匹配,都会产生一个3x3的矩阵HomMat2D用来描述转换。当一张图片中有多个匹配被接受的时候,单应性转换矩阵会串行的保存在tuple中。(应该是很多3x3矩阵串行保存)匹配的个数等于
                                      NumOfMatch =|HomMat2D|/9
NumMatches:用来限制匹配的个数,最多有几个,选择最优的
ScoreType: 可以选择匹配的点的个数或者是相关点的半径两种来表示匹配的优劣程度
所以,这里的Score并不是一个0到1的值,而是一个可能比较大的整数/*
 
count_seconds(Seconds2)
Time:= Seconds2-Seconds1
TotalTime := TotalTime+Time
 
*检测搜索结果是否满足匹配标准,这里利用Score来比较
if ((|HomMat2D|>0) and (Score>NumPoints[Index2] / 4)
(注意这里的NumPoints指的是生成模型时候,对应的兴趣点的个数)
get_descriptor_model_points(ModelIDs[Index2], 'search', 0, Row, Col)
取出上一次搜索的兴趣点,取出第0个匹配的兴趣点(每个匹配都是所有兴趣点的一个子集)
gen_cross_contour_xld(Cross, Row, Col, 6, 0.785398)    */gen_cross_contour_xld( : Cross : Row, Col, Size, Angle : )       根据给出的坐标生成十字星形状的边界/*
*映射变换,把ROI和点进行投影转换, 首先是ROI区域Region
projective_trans_region(Rectangle, TransRegion, HomMat2D, 'bilinear') */projective_trans_region(Regions : TransRegions : HomMat2D, Interpolation : )/*
 
*接下来投影点(这里指的是一开始就给出了定义的RowRoi :=[10, 10, Height-10, Height-*10]和ColRoi := [10, Width-10, Width-10, 10])
projective_trans_pixel(HomMat2D, RowRoi, ColRoi, RowTrans, ColTrans)   
*/projective_trans_pixel( : : HomMat2D, Row, Col : RowTrans, ColTrans)
对给定的Row,Col进行转换,保存到RowTrans,ColTrans中
这里对这几个固定的点进行转换,是为了计算ROI区域偏转的角度,详细见下面Angle_ll的解释/*

angle_ll(RowTrans[2], ColTrans[2],RowTrans[1],ColTrans[1], RowTrans[1],ColTrans[1], RowTrans[0], ColTrans[0], Angle) */angle_ll( : : RowA1, ColumnA1, RowA2, ColumnA2, RowB1, ColumnB1, RowB2, ColumnB2 : Angle) 计算两条线的角度,第一条线 (RowA1,ColumnA1, RowA2,ColumnA2)和第二条线 (RowB1,ColumnB1, RowB2,ColumnB2) ,其中,A1,B1是起点。 这里用于计算矩形区域的两条边之间的角度(不平行边) 注意这里的返回值Angle:是弧度形式Radians, 它的范围在-pi到pi之间/*

Angle := deg(Angle)      把弧度转换成角度,这里是吧1.77...转化为101... */deg等价于弧度  (R/2pi)*360/*

*接下来通过if语句检测这个角度是否可能 if (Angle>70 and Angle<110) area_center(TransRegion, Area, Row, Column) 如果满足条件,则找到一个匹配 ModelsFound :=ModelsFound +1 。。。。设置显示。。。。 endif endif endfor

.......

(3)第三步,清除存储空间 for Index := 0 to |ModelIDs| -1 by 1             clear_descriptor_model(ModelIDs[Index]) endfor

总结:

1,清除模型释放空间, clear_all_descriptor_models()

2,为每个page创建一个描述模型 create_uncalib_descriptor_model

3,为每个模型设置对应的参照点  set_descriptor_model_orgin

4,存储生成的模型中的兴趣点 get_descriptor_model_points   (model)

5,再循环中搜索模型 find_uncalib_descriptor_model

6,获取搜索到的兴趣点 get_descriptor_model_points    (search)完成匹配

7,通过计算转换后的角度来确定这个匹配是否可信 angle_ll

matching书页匹配例子的更多相关文章

  1. [LeetCode] Wildcard Matching 外卡匹配

    Implement wildcard pattern matching with support for '?' and '*'. '?' Matches any single character. ...

  2. Java正则表达式匹配例子

    Java正则表达式匹配例子 package com.ibm.test; import java.util.regex.Matcher; import java.util.regex.Pattern; ...

  3. [LeetCode] 44. Wildcard Matching 外卡匹配

    Given an input string (s) and a pattern (p), implement wildcard pattern matching with support for '? ...

  4. text matching(文本匹配) 相关资料总结

    最近工作上需要做句子语义去重相关的工作,本质上这是属于NLP中text matching(文本匹配)相关的内容.因此我花了一些时间整理了一些关于这个方向的资料,整理如下(也许会持续更新): BiMPM ...

  5. [LeetCode] Regular Expression Matching 正则表达式匹配

    Implement regular expression matching with support for '.' and '*'. '.' Matches any single character ...

  6. [Leetcode] Wildcard matching 通配符匹配

    Implement wildcard pattern matching with support for'?'and'*'. '?' Matches any single character. '*' ...

  7. [LeetCode] 10. Regular Expression Matching 正则表达式匹配

    Given an input string (s) and a pattern (p), implement regular expression matching with support for  ...

  8. 10. Regular Expression Matching字符串.*匹配

    [抄题]: Given an input string (s) and a pattern (p), implement regular expression matching with suppor ...

  9. [LeetCode]10. Regular Expression Matching正则表达式匹配

    Given an input string (s) and a pattern (p), implement regular expression matching with support for ...

随机推荐

  1. LOJ2325. 「清华集训 2017」小 Y 和恐怖的奴隶主【矩阵快速幂优化DP】【倍增优化】

    LINK 思路 首先是考虑怎么设计dp的状态 发现奴隶主的顺序没有影响,只有生命和个数有影响,所以就可以把每个生命值的奴隶主有多少压缩成状态就可以了 然后发现无论是什么时候一个状态到另一个状态的转移都 ...

  2. hadoop入门手册3:Hadoop【2.7.1】初级入门之命令指南

    问题导读1.hadoop daemonlog管理员命令的作用是什么?2.hadoop如何运行一个类,如何运行一个jar包?3.hadoop archive的作用是什么? 概述 hadoop命令被bin ...

  3. Tornado的入门研究

    1.为啥要了解Tornado 首先,Tornado是大神写出来的,如果学习python的话,参照Tornado的源码是一件非常好的事情,属于FaceBook的开源代码 其次,Tornado就是我们在 ...

  4. 【DUBBO】dubbo的LoadBalance接口

    LoadBalance负载均衡, 负责从多个 Invokers中选出具体的一个Invoker用于本次调用,调用过程中包含了负载均衡的算法,调用失败后需要重新选择 --->类注解@SPI说明可以基 ...

  5. LG3953 逛公园

    题意 策策同学特别喜欢逛公园.公园可以看成一张\(N\)个点\(M\)条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,\(N\)号点是公园的出口,每条边有一个非负权值, 代表策策经过这条 ...

  6. normalizr api 转换类库使用

    1. 项目初始化 yarn init yarn add normalizr 项目结构 app.js package.json user.json 2. 使用 a. app.js const userj ...

  7. Git 的分支和标签规则

    Git 的分支和标签规则 分支使用 x.x 命名,不加 V. 标签使用 v1.x.x-xxx 方式命名.(v 为小写) 分支和标签名不可重复.

  8. odoo 使用源码安装时的注意

    odoo 使用源码安装时的注意 使用 odoo 源安装 odoo 时,会增加 odoo 官方的 odoo 源. 安装时直接输入 yum install odoo 即可安装 odoo. 但是更新时就要注 ...

  9. 【转】关于gcc、glibc和binutils模块之间的关系

    原文网址:http://www.mike.org.cn/articles/linux-about-gcc-glibc-and-binutils-the-relationship-between-mod ...

  10. MOSS 2013研究系列---列表的资源限制

    MOSS2010 以后,对列表的条目数做了一些限制,大量的将数据存储在列表中,会降低列表的运行效能,因此,MOSS中对列表默认有了一个阀值,默认是5000条数据,当你存储的数据多余5000条的时候,用 ...