前段時間寫了個簡單的圖像識別程序,主要實現(xiàn)了對螺絲盅弛、螺母、硬幣和小扳手的識別《峒瑁現(xiàn)在來簡單地做一個總結(jié)。
該程序的主要思路如下:
- 將采集到的RGB圖像轉(zhuǎn)化為灰度圖像
- 應用OSTU算法對圖像進行閾值分割并二值化
- 使用區(qū)域生長算法將各個待檢測目標提取出來
- 根據(jù)目標的形狀特征對目標進行分類
接下來對各個步驟做一些分析沉衣。
圖像預處理
圖像預處理是本實驗的第一步郁副。其目的是將目標物體的圖像從背景中分割出來,這樣我們才方便做后續(xù)的識別豌习。
首先將RGB圖像轉(zhuǎn)換為灰度圖像存谎,是為了去除冗余的色彩信息,同時也簡化了計算肥隆。
在灰度圖像的基礎上在進行圖像分割既荚。我們這里采取比較簡單又較為常用的閾值分割法來進行圖像分割。這里使用的OSTU算法是一種具有一定自適應性的閾值分割法栋艳,網(wǎng)絡上有許多對這個算法的詳細說明恰聘,我們這里不加贅述。
區(qū)域生長
雖然通過閾值分割我們已經(jīng)得到了所有目標物體的像素分布吸占,但是僅憑這個我們無法對每個物體的特征進行分析晴叨。因為我們并不知道單獨的每個目標的像素分布。所以我們要尋找一種方法矾屯,將每個物體的像素信息分布保存起來兼蕊。這種方法就是區(qū)域生長算法。區(qū)域生長的核心思想就是從種子點開始向相鄰的點逐點搜索问拘,從而將整個連通區(qū)域提取出來遍略。
以下是該部分的源代碼:
//返回生長區(qū)域點的個數(shù)
int CMainFrame::RegionGrow(Point init, vector<Point> &result, int **mark)
{
stack<Point> seedStack;
Point seed(0,0);
int n = 0; //區(qū)域內(nèi)點的數(shù)量
mark[init.y][init.x] = 1;
seedStack.push(init);
Point tmp(seed.x,seed.y);
while (1)
{
seed = seedStack.top();
seedStack.pop();
if(seed.x < m_pBmpInfo->bmiHeader.biWidth-1)
{
tmp.x = seed.x + 1;
tmp.y = seed.y;
if(!mark[tmp.y][tmp.x] && gImageBuffer[tmp.y*m_pBmpInfo->bmiHeader.biWidth+tmp.x] == 0)
{
seedStack.push(tmp);
result.push_back(tmp);
mark[tmp.y][tmp.x] = 1; //將已被生長的點標記為1
n++; //區(qū)域點的數(shù)量加一
}
}
if(seed.y < m_pBmpInfo->bmiHeader.biHeight-1)
{
tmp.x = seed.x;
tmp.y = seed.y + 1;
if(!mark[tmp.y][tmp.x] && gImageBuffer[tmp.y*m_pBmpInfo->bmiHeader.biWidth+tmp.x] == 0)
{
seedStack.push(tmp);
result.push_back(tmp);
mark[tmp.y][tmp.x] = 1;
n++;
}
}
if(seed.x > 0)
{
tmp.x = seed.x - 1;
tmp.y = seed.y;
if(!mark[tmp.y][tmp.x] && gImageBuffer[tmp.y*m_pBmpInfo->bmiHeader.biWidth+tmp.x] == 0)
{
seedStack.push(tmp);
result.push_back(tmp);
mark[tmp.y][tmp.x] = 1;
n++;
}
}
if(seed.y > 0)
{
tmp.x = seed.x;
tmp.y = seed.y - 1;
if(!mark[tmp.y][tmp.x] && gImageBuffer[tmp.y*m_pBmpInfo->bmiHeader.biWidth+tmp.x] == 0)
{
seedStack.push(tmp);
result.push_back(tmp);
mark[tmp.y][tmp.x] = 1;
n++;
}
}
if(seedStack.empty())
break;
}
return n;
}
目標識別
在得到了各個目標的像素信息后惧所,如何對目標進行分類呢骤坐?由于我們要識別的物體僅限于螺絲、螺母下愈、硬幣這樣形狀簡單的物體纽绍,我們只需通過一些簡單的特征就能將他們區(qū)分開來。
- 螺母的中心為空势似,而螺絲拌夏、小扳手均為實心
- 小扳手為L形的細桿,其長軸和短軸之比遠大于螺絲
- 硬幣為圓形
憑借以上三條規(guī)則履因,就足以將螺絲障簿、螺母、硬幣和扳手區(qū)分開來了栅迄。
小結(jié)
本文主要是整理思路站故,細節(jié)的地方并未涉及,希望能對讀者有一些幫助~
P.S. 此文在我新搭建的獨立博客亦有發(fā)表:
http://cyanair.me/2016/03/31/a-simple-objection-recognition-program/