碼農干貨系列【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.pswp.cn/news/377319.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/377319.shtml
英文地址,請注明出處:http://en.pswp.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…