任志敏
(常州紡織服裝職業(yè)技術學院機電學院,江蘇 常州 213164)
隨著無人駕駛、人工智能及5G技術的飛速發(fā)展,越來越多的智能新技術應用產(chǎn)品深入尋常百姓家。不管是哪一種產(chǎn)品,少不了Android系統(tǒng)的身影。作為智能化產(chǎn)品的標志之一,類人的視覺系統(tǒng)是必不可少的,其中對顏色和形狀的識別又是最基本的。因此,本文將著重解決android平臺下顏色和形狀識別的問題。
關于顏色及形狀的識別在PC機平臺下已經(jīng)比較成熟,但是在Android平臺下受制于軟硬件系統(tǒng)的局限性,該技術有待進一步研究。
Android系統(tǒng)的內(nèi)核是由C/C++設計的Linux系統(tǒng),其上層支持Java和Kotlin編程語言,目前國內(nèi)主流使用的仍舊是Java。第一種方案是直接在Android平臺上使用Java語言實現(xiàn)顏色和形狀識別算法,但是比起C/C++語言,使用Java語言進行圖像處理的效率沒那么高,因此,直接使用Java語言進行圖像處理不是最佳的選擇。第二種方案是采用已有的成熟的圖像處理庫,在Android平臺下調(diào)用庫實現(xiàn)顏色和形狀識別。現(xiàn)有的主流圖像處理庫有OpenCv,CxImage,F(xiàn)reeImage,AForge等。
OpenCV的全稱是Open Source Computer Vision Library,是一個基于BSD許可(開源)發(fā)行的跨平臺計算機視覺庫,又名“開源計算機視覺庫”。OpenCV可運行在Windows、Android、Maemo、FreeBSD、OpenBSD、iOS、Linux和Mac OS等平臺。OpenCV提供了各種圖像處理算法,用戶通過組合算法實現(xiàn)需要的功能。
CxImage類庫是一個優(yōu)秀的圖像操作類庫。它可以快捷地存取、顯示、轉換各種圖像。對Windows、MFC支持極好,支持圖像的多種操作(線性濾波、中值濾波、直方圖操作、旋轉縮放、區(qū)域選取、閾值處理、膨脹腐蝕、alpha混合等)。
FreeImage也是一個開放源碼庫項目,為開發(fā)人員提供支持當今多媒體應用程序所需的流行圖形圖像格式,如PNG、BMP、JPEG、TIFF等。FreeImage易于使用,速度快,多線程安全,兼容所有32位或64位版本的Windows,也支持Linux和Mac OS X。
AForge.NET是一個專門為開發(fā)者和研究者基于C#框架設計的,該框架提供了不同的類庫和關于類庫的資源,還有很多應用程序例子,包括計算機視覺與人工智能,圖像處理,神經(jīng)網(wǎng)絡,遺傳算法,機器學習,機器人等領域。
綜合比較,OpenCV因其優(yōu)秀的跨平臺性,已經(jīng)是目前PC平臺下最主流的圖像處理庫,并已經(jīng)通過了大量工程應用的考驗,因此,本文選擇OpenCV為顏色形狀識別的支持庫。OpenCV提供了基于Android平臺的SDK,支持3種方式接入Android。
第一種方式適用于對OpenCVc++不熟悉的用戶,不需要直接調(diào)用C++方案,因為官方提供的SDK已經(jīng)用JNI全部封裝好了。用戶只需要安裝好JDK、AndroidStudio與NDK環(huán)境。
第二種方式是使用OpenCVSDK提供的C++頭文件、.so動態(tài)庫和.a靜態(tài)庫,用戶自己封裝JNI,該方式使用的效率會比第一種方法高一些,且可以100%使用OpenCV的接口[1]。
第三種方式通過OpenCV的源碼,重新編譯成Android SDK庫,這樣的好處是能獲取到OpenCV最新的功能,缺點是編譯較為復雜,且新的代碼或許會存在不兼容與錯誤。
綜合比較以上三種方式的優(yōu)缺點,本文使用第二種方式,通過JNI調(diào)用OpenCV提供的API,使用C++語言操作OpenCV的接口。
為了驗證顏色形狀識別的可行性與可靠性,本文設定的識別目標為4種顏色(紅色、綠色、黃色和藍色),5種形狀(長方形、正方形、三角形、多邊形和圓)。如圖1所示。
圖1 顏色形狀識別樣圖
第一步建立Androidstudio平臺下OpenCv的JNI開發(fā)環(huán)境[2]。本文使用的版本是Android Studio3.2和OpenCv3.4.2-android-sdk。如圖2所示。
第二步:設計APP(Java語言)。如圖3所示。
一共設計了4個控件,包括2個Button,1個ImageView,1個TextView?!斑x擇…”按鈕用于打開Android系統(tǒng)的圖片目錄,選擇需要識別的圖片。ImageView用于顯示選擇的待識別圖片?!靶螤铑伾R別”按鈕用于執(zhí)行具體的識別程序。APP底部的TextView控件用于顯示識別的結果。
圖2 android studio及opencv開發(fā)環(huán)境
圖3 顏色形狀識別APP布局文件
因為要讀取Android的系統(tǒng)圖片目錄,需要首先在AndroidManifest.xml文件中設置允許讀外部存儲器權限。即:
若使用的androidSDK是23及以上版本,還需要在程序中設置運行時允許讀權限。
因為打開Android系統(tǒng)圖片目錄是一個新的Activity,該Activity需要向MainActivity回傳圖片路徑信息,因此使用startActivityForResult(Intent intent, int requestCode)方法打開新的Activity,并把圖片文件回傳給MainActivity中的變量fileUri。設計顏色形狀識別函數(shù)
private void colorShapeDector() {
Mat image = Imgcodecs.imread(fileUri.getPath());
if(image.empty()) {
return;
}
strResult = DetectShapeColor(image.getNativeObjAddr());
tvResult.setText(strResult);
調(diào)用imread獲取待識別圖片的數(shù)據(jù)元素。通過image.getNativeObjAddr()方法把Java端獲得的路徑轉換為OpenCV端可識別的路徑。
第三步:設計顏色形狀識別程序(C++語言)
在native-lib.cpp聲明識別函數(shù)名稱、參數(shù)和返回值。
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_sidneyren_firstdemo_MainActivity_DetectShapeColor(
JNIEnv *env,
jobject /* this */,
jlong addrInputRgbaImage
)
S1:為了增強識別的魯棒性,轉換圖片的顏色空間,由RGB轉換為HSV。cvtColor(img,imgHSV,COLOR_BGR2HSV);其中img為原始圖像,imgHSV為轉換后的圖像。
S2:設置待識別顏色的HSV三個分量的上下限閾值,以綠色為例,greenLowH=35,greenHighH=77,greenLowS=43,greenHighS=255,greenLowV=46,greenHighV=255。調(diào)用inRange(imgHSV,Scalar(greenLowH,greenLowS,greenLowV),Scalar(greenHighH,greenHighS,greenHighV),imgThresholded)函數(shù)對imgHSV圖像進行分割,位于綠色HSV上下限區(qū)間內(nèi)的像素點設置為255,不在該范圍內(nèi)的像素點設置為0,即生成一個二值化圖像[3],分割后生成的圖像imgThresholded如圖4所示。
圖4 分割后的圖像
S3:調(diào)用形態(tài)學操作函數(shù):element=getStructuringElement(MORPH_RECT, Size(5,5));對圖像進行腐蝕和膨脹。調(diào)用函數(shù)morphologyEx對圖像進行開閉操作,并提取輪廓,處理后的圖像如圖5所示。
圖5 腐蝕、膨脹后的圖像
S4:設計形狀識別的類ShapeDetector。
調(diào)用arcLength函數(shù)計算封閉輪廓的周長。調(diào)用approxPolyDP函數(shù)對圖像輪廓點進行多邊形擬合,從而獲得輸出的多邊形點集,通過判斷多邊形點集的數(shù)量判斷具體是哪種形狀。
S5:遍歷圖像中所有輪廓,調(diào)用形狀識別類,即可識別具體某一種顏色塊的所有形狀。
S6:設置紅色、黃色和藍色的HSV上下限閾值,重復步驟S3~S5即可識別4種顏色塊的形狀。
本文一共使用100張各種形狀的圖片來驗證APP的識別準確率,圖片分成形狀和顏色不連接的部分和連接的部分,結果形狀和顏色均不連接的圖片識別準確率為100%,形狀和顏色連接的圖片有一張未能準確識別,總體識別準確率為99%。