码农干货系列【4】--图像识别之矩形区域搜索

简介

定位某个图片的矩形区域是非常有用的,这个可以通过手动的选择某个区域来实现定位,图片相关的软件都提供了这个功能;也可以像本篇一个通过程序来实现智能定位。前者会有误差,效率低下;后者选区精度高,效率高。

应用场景

1.精灵编辑器或者css sprites辅助工具(当我们需要逆着TexturePacker行事的时候),如下图所示:

image

2.手写识别输入

image image

因为我们不能保证用户输入的区域,所以必须定位到用户输入的区域,再去识别用户的输入的内容。

3.魔法画板程序

比如马良神笔,要对用户绘制的火柴人进行一些上下左右移动、扭曲等效果:

image

矩形区域识别

废话一万句,不如一张图。看下面这张图:

image

这就是识别的关键。任意取图像上的一点,然后通过这点开始扩张。一般情况下,该点取的是软件使用者鼠标点击的那一点。如图是移动中的四个点:

image

可以看到,移动后的四个点可以确定一个矩形区域。哪条边下的所有像素为透明(即0,0,0,0),则该点不移动,等待其他点移动完成。当所有边下面的像素都为透明,则得到了我们想要的区域。我们根据移动的距离可以很方便的找到四个顶点:

image

所以一个递归就可以帮我们实现(js Canvas版):


var increasePixel = 1, leftIncreasePixel = 2, rightIncreasePixel = 2, upIncreasePixel = 2, downIncreasePixel = 2;
function searchTransparentRectByTargetPoint(p) {

var p1 = { x: p.x - leftIncreasePixel, y: p.y - upIncreasePixel };
var p2 = { x: p.x + rightIncreasePixel, y: p.y - upIncreasePixel };
var p3 = { x: p.x + rightIncreasePixel, y: p.y + downIncreasePixel };
var p4 = { x: p.x - leftIncreasePixel, y: p.y + downIncreasePixel };

var breakTag = true;
if (!isXLineTransparent(p1, p2)) {
upIncreasePixel += increasePixel;
breakTag = false;
}
if (!isYLineTransparent(p2, p3)) {
breakTag = false;
rightIncreasePixel += increasePixel;
}
if (!isXLineTransparent(p4, p3)) {
breakTag = false;
downIncreasePixel += increasePixel;
}
if (!isYLineTransparent(p1, p4)) {
breakTag = false;
leftIncreasePixel += increasePixel;
}

if (breakTag) {
return [p1.x, p1.y, p3.x - p1.x, p3.y - p1.y];
} else {
return searchTransparentRectByCenterPoint(p);
}
}

其中isXLineTransparent和isYLineTransparent是获取该线段下面是否全透明。


function isXLineTransparent(p1, p2) {
var _y = p2.y;
for (var i = p1.x; i < p2.x + 1; i++) {
var startIndex = this.getImageDataStartIndexByPosition({ x: i, y: _y });
var totalPixel = this.imageData.data[startIndex] + this.imageData.data[startIndex + 1] + this.imageData.data[startIndex + 2] + this.imageData.data[startIndex + 3];
if (totalPixel !== 0) {
return false;
}
}
return true;
}

function isYLineTransparent(p1, p2) {
var _x = p2.x;
for (var i = p1.y; i < p2.y + 1; i++) {
var startIndex = this.getImageDataStartIndexByPosition({ x: _x, y: i });
var totalPixel = this.imageData.data[startIndex] + this.imageData.data[startIndex + 1] + this.imageData.data[startIndex + 2] + this.imageData.data[startIndex + 3];
if (totalPixel !== 0) {
return false;
}
}
return true;
}

多矩形区域识别策略

多矩形区域识别是没有扩张点,需要从用户输入中随机产生一个目标点,然后使用两层递归(上面的代码之外再嵌套一层)实现所有矩形区域的遍历。

image

思路有了,是不是有想法把上面的手写输入改成支持多个文字?这个对于聪明的你,明显不是问题。

在线演示

传送门:http://www.spritecow.com/

转载于:https://www.cnblogs.com/iamzhanglei/archive/2012/07/23/2604313.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/377319.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android中的广播Broadcast详解

今天来看一下Android中的广播机制&#xff0c;我们知道广播Broadcast是Android中的四大组件之一&#xff0c;可见他的重要性了&#xff0c;当然它的用途也很大的&#xff0c;比如一些系统的广播&#xff1a;电量低、开机、锁屏等一些操作都会发送一个广播&#xff0c;具体的And…

.NET线程池

摘要 深度探索 Microsoft .NET提供的线程池&#xff0c; 揭示什么情况下你需要用线程池以及 .NET框架下的线程池是如何实现的&#xff0c;并告诉你如何去使用线程池。 内容 介绍 .NET中的线程池 线程池中执行的函数 使用定时器 同步对象的执行 异步I/O操作 监视线程池 死锁 有关…

《c++特性》

目录多态构造函数和析构函数存在多态吗&#xff1f;虚函数表虚析构函数纯虚函数和抽象类运行时多态和编译时多态的区别继承设计实例指针对象和普通对象的区别正确初始化派生类方式继承和赋值的兼容规则protected 和 private 继承基类与派生类的指针强制转换如何用C实现C的三大特…

Scala中的while循环

在Scala中的while循环 (while loop in Scala) while loop in Scala is used to run a block of code multiple numbers of time. The number of executions is defined by an entry condition. If this condition is TRUE the code will run otherwise it will not run. Scala中…

牛客网与leetcode刷题(高频题中简单or中等的)

目录1、反转链表2、排序3、先序中序后序遍历4、最小的k个数5、子数组的最大累加和6、 用两个栈实现队列7、142. 环形链表 II8、20. 有效的括号9、最长公共子串(动态规划),磕磕绊绊10、二叉树之字形层序遍历11、重建二叉树12、LRU缓存13、合并两个有序链表15、大数加法16、一个二…

AMUL的完整形式是什么?

AMUL&#xff1a;阿南德牛奶联盟有限公司 (AMUL: Anand Milk Union Limited) AMUL is an abbreviation of Anand Milk Union Limited. It is an Indian milk product cooperative dairy organization that is based in the small town of Anand in the state of Gujarat. AMUL …

mochiweb 源码阅读(十一)

大家好&#xff0c;今天周六&#xff0c;继续接着上一篇&#xff0c;跟大家分享mochiweb源码。上一篇&#xff0c;最后我们看到了mochiweb_socket_server:listen/3函数&#xff1a; listen(Port, Opts, State#mochiweb_socket_server{sslSsl, ssl_optsSslOpts}) ->case moch…

Android下拉刷新完全解析,教你如何一分钟实现下拉刷新功能 (转)

转载请注明出处&#xff1a;http://blog.csdn.net/guolin_blog/article/details/9255575 最 近项目中需要用到ListView下拉刷新的功能&#xff0c;一开始想图省事&#xff0c;在网上直接找一个现成的&#xff0c;可是尝试了网上多个版本的下拉刷新之后发现效果都不怎么理 想。有…

红黑树的实现

目录1、红黑树原理1、红黑树性质2、变换规则&#xff08;从插入结点的角度来讲&#xff09;1.变色2.左旋3.右旋3、删除结点需要注意的地方2、代码1、定义结点以及构造函数2、定义红黑树类以及声明它的方法3、左旋4、右旋5、插入操作6、修正操作7、删除操作3、参考链接1、红黑树…

118 - ZOJ Monthly, July 2012

http://acm.zju.edu.cn/onlinejudge/showContestProblems.do?contestId339 都是赛后做的。。。弱爆了 A题是找由2和5组成的数字的个数 直接打个表就行了 只是比赛的时候不知道怎么打表啊。。 View Code #include<cstdio> #include<cstring> #include<algorith…

edp1.2和edp1.4_EDP​​的完整形式是什么?

edp1.2和edp1.4EDP​​&#xff1a;电子数据处理 (EDP: Electronic Data Processing) EDP is an abbreviation of Electronic Data Processing. It alludes to the functioning of operations of commercial data, documents processing of storing, with the use of a compute…

css链接样式_CSS中的样式链接

css链接样式CSS样式链接 (CSS Styling Links) The links in CSS can be styled in various ways to make our website more presentable and attractive. The links can also be styled depending on their states e.g. visited, active, hover, etc. CSS中的链接可以通过各种方…

css中的媒体查询_CSS中的媒体查询

css中的媒体查询CSS | 媒体查询 (CSS | Media Queries) Creating a web page is not an easy task as it requires loads of content and data so that it becomes strongly responsive to the users. To do that various contents are even added e.g.: resources, informativ…

SharePoint2013安装组件时AppFabric时出现1603错误,解决方法:

采用PowerShell命令批量下载必备组件: 下载完成后&#xff0c;采用批处理命令安装必备组件。 注&#xff1a;SPS2013安装必备组件及批处理下载地址&#xff1a; 需要将必备组件放在安装文件的PrerequisiteInstallerFiles文件夹中&#xff0c;将PreReq2013.bat放在安装文件根目录…

《MySQL——数据表设计三大范式》

目录数据表设计范式第一范式第二范式第三范式数据表设计范式 第一范式 数据表中的所有字段都是不可分割的原子值。 字段值还可以继续拆分的&#xff0c;就不满足第一范式&#xff0c;如下&#xff1a; 下面这个&#xff0c;更加贴合第一范式&#xff1a; 范式设计得越详细&…

三道简单树型dp+01背包~~hdu1561,poj1947,zoj3626

以前学树型dp就是随便的看了几道题&#xff0c;没有特别注意树型dp中的小分类的总结&#xff0c;直到上次浙大月赛一道很简单的树型dp都不会&#xff0c;才意识到自己太水了&#xff5e;&#xff5e;come on&#xff01; hdu1561&#xff1a;题目给出了很多棵有根树&#xff0c…

css 字体图标更改颜色_在CSS中更改字体

css 字体图标更改颜色CSS字体属性 (CSS font properties ) Font properties in CSS is used to define the font family, boldness, size, and the style of a text. CSS中的字体属性用于定义字体系列 &#xff0c; 粗体 &#xff0c; 大小和文本样式 。 Syntax: 句法&#xf…

C++基础知识点整理

基本语法 1、static关键字的作用 1、全局静态变量 加了static关键字的全局变量只能在本文件中使用。 存储在静态存储区&#xff0c;整个程序运行期间都存在。 2、局部静态变量 作用域仍为局部作用域。 不过离开作用域之后&#xff0c;并没有销毁&#xff0c;而是贮存程序中&a…

组合问题 已知组合数_组合和问题

组合问题 已知组合数Description: 描述&#xff1a; This is a standard interview problem to make some combination of the numbers whose sum equals to a given number using backtracking. 这是一个标准的面试问题&#xff0c;它使用回溯功能将总和等于给定数字的数字进…

可变参数模板、右值引用带来的移动语义完美转发、lambda表达式的理解

可变参数模板 可变参数模板对参数进行了高度泛化&#xff0c;可以表示任意数目、任意类型的参数&#xff1a; 语法为&#xff1a;在class或者typename后面带上省略号。 Template<class ... T> void func(T ... args) {// }T:模板参数包&#xff0c;args叫做函数参数包 …