大家好,給大家介紹一下,這是基於FPGA的膚色識別算法實現。
我們今天這篇文章有兩個內容一是實現基於FPGA的彩色圖片轉灰度實現,然后在這個基礎上實現基於FPGA的膚色檢測算法實現。
將彩色圖像轉化為灰度的方法有兩種,一個是令RGB三個分量的數值相等,輸出后便可以得到灰度圖像,另一種是轉化為YCbCr格式,將Y分量提取出來,YCbCr格式中的Y分量表示的是圖像的亮度和濃度所以只輸出Y分量,得到的圖像就是灰度圖像了。我在這里選擇第二種方法實現。
YCBCr是通過有序的三元組來表示的,三元由Y(Luminance)、Cb(Chrominance-Blue)和Cr(Chrominance-Red)組成,其中Y表示顏色的明亮度和濃度,而Cb和Cr則分別表示顏色的藍色濃度偏移量和紅色濃度偏移量。人的肉眼對由YCbCr色彩空間編碼的視頻中的Y分量更敏感,而Cb和Cr的微小變化不會引起視覺上的不同,根據該原理,通過對Cb和Cr進行子采樣來減小圖像的數據量,使得圖像對存儲需求和傳輸帶寬的要求大大降低,從而達到在完成圖像壓縮的同時也保證了視覺上幾乎沒有損失的效果,進而使得圖像的傳輸速度更快,存儲更加方便。我們要的到灰度圖像,首先要將采集到的彩色圖像轉化為YCbCr。
我通過串口發送的彩色圖片數據是RGB332 8bit,根據官方給出的轉化公式是RGB888->YCbCr,所以我首先要將8bit RGB332轉化為24bit RGB888。轉化如下,這里用到了循環補償的概念。
從如上轉化可以看出,B分量進行了四輪補償。進行這樣的補償,在做色彩格式轉化的時候,能夠明顯的改善色彩效果,減少精度上的損失。代碼實現部分如下。
下面是官方給的RGB888 to YCbCr的算法公式,我們可以直接把算法移植到FPGA上,但是我們都知道FPGA無法進行浮點運算,所以我們采取將整個式子右端先都擴大256倍,然后再右移8位,這樣就得到了FPGA擅長的乘法運算和加法運算了。
這個計算式子看起來是十分簡單的,但是要是直接用Verilog直接寫出來,那么只能說,這個人的代碼寫的一塌糊塗,所以這里就引出FPGA中流水線的設計思想。
在這里我們選擇加3級流水線,就第一個Y分量而言,先計算括號中得乘法運算,消耗一個時鍾,然后將括號中的數據求和,消耗一個時鍾,這里為了計算方便,將128也擴大256倍,放到括號中,最終結果除以256就行了也就是右移8位,在FPGA中我們只需要舍棄低8位取高8位就行。
將RGB565—>YCbCr成功后,提取出Y的值輸出,就可以得到灰度色彩的圖像了。
將采集到的RGB565的像素數據,輸入到算法處理模塊進行操作,由RGB565——>YCbCr——Gray官方給出的公式來算,先將RGB565拆分開R G B三個分量,使用如上公式計算的到Y Cb Cr是三個分量。
RGB轉YCbCr算法的仿真過程,從圖中可以看出,加了流水線后的運算過程,每一級運算相差一個時鍾,然而每一級都在進行新的運算,我們加了3級流水線,這樣運算速度可以提升3倍。
最后將Y分量的數據輸出,進行位拼接,16位的RGB565像素R、G、B分量分別對應的取Y分量的高位,最后的輸出顯示出來就是灰度圖像了。
視頻演示請看我微博鏈接http://t.cn/RO9DJoZ
對於膚色檢測其實也是基於這個基礎上,首先利用如上圖公式將RGB轉化為YCbCr,然后通過對Cb和Cr分量設置閾值,我這邊設置的是當Cb和Cr分量在這個閾值之間時,輸出為全1,即白色,其他情況輸出為全0,即為黑色,我使用前面的200x200的圖片做實驗,效果不怎么好,最后借用業界前輩CrazyBingo大神的攝像頭驅動,試了一下這個膚色識別算法,最后得到的效果還是可以的。這個用YCbCr閾值法實現膚色識別的方法,是不很精確,后面我會嘗試用另一種識別方法來試着實現。
膚色識別YCbCr閾值
77 < Cb < 127
133 < Cr < 173

最終的效果如下視頻:http://t.cn/ROwEnrb
如果你想獲得本文的所有課件,請關注本人的個人微信訂閱號:開源FPGANingHeChuan或掃描下方二維碼關注訂閱號,在后台回復圖像處理,即可獲得本文的所有課件、資料以及更多FPGA的學習資料哦!

轉載請注明出處:NingHeChuan(寧河川)
個人微信訂閱號:開源FPGANingHeChuan
如果你想及時收到個人撰寫的博文推送,可以掃描左邊二維碼(或者長按識別二維碼)關注個人微信訂閱號
知乎ID:NingHeChuan
微博ID:NingHeChuan
原文地址:http://www.cnblogs.com/ninghechuan/p/7574309.html
圖像處理系列文章
第一篇:基於FPGA的VGA顯示靜態圖片
