码农干货系列【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,一经查实,立即删除!

相关文章

算法题复习(回溯)

目录base code棋盘问题51. N 皇后37. 解数独组合问题77. 组合未剪枝优化剪枝优化216. 组合总和 III未剪枝优化剪枝优化17. 电话号码的字母组合39. 组合总和未剪枝优化剪枝优化40. 组合总和 II,挺重要的&#xff0c;涉及到去重了切割问题131. 分割回文串子集问题78. 子集90. 子集…

pfa是什么意思_PFA的完整形式是什么?

pfa是什么意思PFA&#xff1a;预测性故障分析 (PFA: Predictive Failure Analysis) PFA is an abbreviation of Predictive Failure Analysis. It is a technique of a mechanism of the computer that is used to predict impending failures of software or hardware compone…

SqlServer视图(view)

--上节回顾--1.什么是事务--2.事务的特征--原子性、一致性、隔离性、持久性--3.与事务相关的t-sql命令--开启事务&#xff1a;begin transaction--提交事务&#xff1a;commit transaction--回滚事务&#xff1a;rollback transaction ----------------视图-------------------…

Android中的广播Broadcast详解

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

sql check约束_在SQL中使用CHECK约束

sql check约束Basically, CHECK constraint is used to LIMIT in columns for the range of values. We can use this constraint for single or multiple columns. 基本上&#xff0c; CHECK约束用于限制值范围内的列 。 我们可以将此约束用于单列或多列。 In single column,…

.NET线程池

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

折线分割平面

Input输入数据的第一行是一个整数C,表示测试实例的个数&#xff0c;然后是C 行数据&#xff0c;每行包含一个整数n(0<n<10000),表示折线的数量。Output对于每个测试实例&#xff0c;请输出平面的最大分割数&#xff0c;每个实例的输出占一行。Sample Input2 1 2Sample Ou…

《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中…

Linux操作系统启动过程

在做开发的过程中&#xff0c;突然发现&#xff0c;要对系统做一些有意义的改变&#xff0c;必须要对操作系统的启动过程有一定的了解&#xff0c;不然就是修改你都不知道从哪里下手啊&#xff0c;然后就是找来资料看&#xff0c;去网上看别人的博客&#xff0c;有了前一周一些…

方法命名的区别

GetDecimalFromString ExtractDecimal 这2个方法名那个比较好呢。上边的明显的是中式英语&#xff0c;单词拼凑而成的。下边的更加流畅一些。方法名称取名还是很有要求的。要通俗易懂还要符合文法。从上边的可以扩展出什么想法呢。 ExtractDecimalExtractDoubleExtractInt16Ext…

工作排序问题

Problem statement: 问题陈述&#xff1a; Given an array of jobs where every job has a deadline and a profit. Profit can be earned only if the job is finished before the deadline. It is also given that every job takes a single unit of time, so the minimum p…

牛客网与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;可是尝试了网上多个版本的下拉刷新之后发现效果都不怎么理 想。有…

Python中的append()和extend()

列出append()方法 (List append() method) append() method is used to insert an element or a list object to the list and length of the List increased by the 1. append()方法用于将元素或列表对象插入列表&#xff0c;并且列表长度增加1。 Syntax: 句法&#xff1a; …

红黑树的实现

目录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…