楊 豪 盧興來 胡利軍 李從初 顏?zhàn)谌A 徐振宇 姚浩立
(1.寧波市氣象網(wǎng)絡(luò)與裝備保障中心,浙江 寧波 315012; 2.浙江省大氣探測(cè)技術(shù)保障中心,浙江 杭州 310017)
利用圖像識(shí)別技術(shù)的積雪輔助判別
楊 豪1盧興來2胡利軍1李從初1顏?zhàn)谌A1徐振宇1姚浩立1
(1.寧波市氣象網(wǎng)絡(luò)與裝備保障中心,浙江 寧波 315012; 2.浙江省大氣探測(cè)技術(shù)保障中心,浙江 杭州 310017)
提出了一種基于開源計(jì)算機(jī)視覺庫OpenCV的圓形檢測(cè)方法協(xié)助訂正自動(dòng)雪深儀的疑誤數(shù)據(jù)。對(duì)測(cè)雪板上的圖像識(shí)別區(qū)域依序進(jìn)行平滑濾波處理、邊緣檢測(cè)、Hough變換圓檢測(cè),識(shí)別出積雪情況。利用該方法,提高了疑誤數(shù)據(jù)的訂正效率。
雪深;圖像識(shí)別;OpenCV;Hough
近年來,浙江省先后建成了160余套自動(dòng)雪深觀測(cè)儀,在浙江省冰雪災(zāi)害監(jiān)測(cè)中發(fā)揮了重要作用。然而,在實(shí)際應(yīng)用中,發(fā)現(xiàn)存在一些錯(cuò)誤數(shù)據(jù)。本文從圖像處理的角度出發(fā),對(duì)積雪深度圖進(jìn)行有效判別,從而剔除錯(cuò)誤數(shù)據(jù)。
大部分雪深觀測(cè)儀的基本原理是利用激光單點(diǎn)測(cè)距來測(cè)量積雪深度,主要傳感器就是激光測(cè)距單元。安裝時(shí)在立柱上固定好測(cè)距單元,在立柱前正對(duì)著測(cè)距單元的地面上安裝柵格型測(cè)雪板,確保測(cè)雪面的水平。調(diào)整測(cè)距單元使紅色激光點(diǎn)照在測(cè)雪板中心的圓形測(cè)雪點(diǎn)上,以便標(biāo)定雪深觀測(cè)基準(zhǔn)面,保證雪深觀測(cè)的準(zhǔn)確性。
在冬季下雨或是凍雨后,氣溫降低到了冰點(diǎn)附近,導(dǎo)致濕潤的土壤出現(xiàn)結(jié)冰膨脹,土壤的凍脹使測(cè)雪板被土壤頂起,導(dǎo)致雪深測(cè)量出現(xiàn)錯(cuò)誤數(shù)據(jù)。另外,在日常的維護(hù)或是標(biāo)定過程中由于操作不當(dāng)?shù)仍蛞部赡艹霈F(xiàn)錯(cuò)誤數(shù)據(jù)。
從雪深觀測(cè)站的海拔高度、當(dāng)時(shí)的氣溫、濕度條件來人工判斷是否可能有降雪和積雪。最為直觀的方法是通過采集測(cè)雪板上的圖像信息直接判斷是否確實(shí)有積雪。通過圖像識(shí)別技術(shù)可自動(dòng)從測(cè)雪板的圖像上識(shí)別出是否有積雪現(xiàn)象,提高排查雪深疑誤數(shù)據(jù)效率。
在自然背景條件下通過圖像對(duì)測(cè)雪板上的圓形測(cè)雪點(diǎn)進(jìn)行積雪自動(dòng)識(shí)別具有一定的難度,照明、陰影遮擋、空氣污染、氣候條件(雨、霧等)都會(huì)直接影響到圖像識(shí)別的準(zhǔn)確性。為確保圖像識(shí)別的準(zhǔn)確性,可先截取圖像需要識(shí)別的區(qū)域,過濾掉大部分無關(guān)背景,然后進(jìn)行顏色過濾,轉(zhuǎn)換為灰度圖像并做圖像平滑處理,減少圖像的噪聲以利于最終結(jié)果的檢測(cè)。
使用Hough變換方法對(duì)預(yù)處理的圖像進(jìn)行邊緣檢測(cè),其原理是利用兩個(gè)坐標(biāo)空間之間的變換將一個(gè)空間中具有相同形狀的曲線或直線映射到另一個(gè)坐標(biāo)空間的一個(gè)點(diǎn)上形成峰值,從而把檢測(cè)任意形狀的問題轉(zhuǎn)化為統(tǒng)計(jì)峰值問題。使用Hough變換的優(yōu)點(diǎn)是,檢測(cè)到一個(gè)圓之后就能得到這個(gè)圓的位置和半徑數(shù)據(jù)信息,有了這些數(shù)據(jù)信息就可以用來從測(cè)雪板圖像上提取出圓形測(cè)雪點(diǎn)的區(qū)域,然后再針對(duì)這個(gè)圓形區(qū)域進(jìn)行重點(diǎn)識(shí)別。
OpenCV是英特爾公司為實(shí)時(shí)應(yīng)用進(jìn)行優(yōu)化的C/C++計(jì)算機(jī)視覺庫[1]。它開源、高效、便于移植和擴(kuò)展,提供多種語言接口,實(shí)現(xiàn)了很多圖像處理和計(jì)算機(jī)視覺的通用算法[2]。在其官方網(wǎng)站opencv.org上可以下載到針對(duì)不同操作系統(tǒng)的OpenCV。通過編譯源代碼,生成適合實(shí)際生產(chǎn)環(huán)境的庫文件。
3.1 HoughCircles函數(shù)介紹
OpenCV中對(duì)圓的檢測(cè)方法是HoughCircles函數(shù),該方法就是利用Hough變換梯度算法檢測(cè)出灰度圖中的圓。其原函數(shù)為:
void cv::HoughCircles(InputArray _image, OutputArray _circles, int method, double dp, double min_dist, double param1, double param2, int minRadius, int maxRadius)
通常情況下,該函數(shù)檢測(cè)圓的中心是有效的。然而,它可能無法找到正確半徑。如果知道待測(cè)圓的大概半徑,就可通過半徑范圍設(shè)置找到合適的圓。
在實(shí)際應(yīng)用中,要注意參數(shù)的選擇,選擇合適的參數(shù)得到的圓位置和半徑也就越準(zhǔn)確。圖1a圖的邊緣檢測(cè)閾值25,圖1b圖的邊緣檢測(cè)閾值70,圖1c圖的邊緣檢測(cè)閾值105。圖2a圖是圖1a的圓檢測(cè)結(jié)果,圖2b圖是圖1b和圖1c的圓檢測(cè)結(jié)果。
(a圖的邊緣檢測(cè)閾值25、b圖的邊緣檢測(cè)閾值70、c圖的邊緣檢測(cè)閾值105)圖1 不同邊緣檢測(cè)閾值的檢測(cè)結(jié)果
(a圖是圖1a的圓檢測(cè)結(jié)果、b圖是圖1b和圖1c的圓檢測(cè)結(jié)果)圖2 不同邊緣檢測(cè)閾值的圓檢測(cè)結(jié)果
3.2 開發(fā)環(huán)境搭建
開發(fā)環(huán)境的搭建工具下載、編譯器配置、建立解決方案等。
下載OpenCV源代碼和cmake-gui工具,運(yùn)行cmake-gui.exe,選擇OpenCV源代碼路徑和生成路徑。
配置編譯器,考慮到圖像處理需要大量耗費(fèi)CPU、GPU和內(nèi)存資源建議選擇Win64。
解決方案生成,點(diǎn)擊Finish按鈕,CMake開始自動(dòng)配置,配置結(jié)束后顯示Configuring done。接著建立解決方案,通過點(diǎn)擊Generate按鈕自動(dòng)在x64build下建立解決方案。
啟動(dòng)Visual Studio 2015,打開x64build下的OpenCV解決方案,重新生成解決方案。在解決方案資源管理器中,展開CMakeTarget目錄,右鍵其中的INSTALL工程,選擇“僅用于項(xiàng)目”中的“僅生成INSTALL”,在x64build/install/x64/vc14下就可以看到有很多64位環(huán)境下的OpenCV庫文件。
建立基于.Net Framework 4.0的Windows Forms解決方案,在解決方案中添加所需的OpenCV庫文件。OpenCV有很多強(qiáng)大的功能,本文敘述利用Hough變換來檢測(cè)圓形的功能,因此只需要添加opencv_core.dll、opencv_imgproc.dll、opencv_highgui.dll這幾個(gè)類庫文件。引入的64位OpenCV類庫,將解決方案生成目標(biāo)平臺(tái)修改為x64。
分辨率、寬度、高度、像素位深度、顏色空間是處理圖像最基本幾個(gè)要素。像素位深度、顏色空間很常用,因此將像素位深度和顏色空間轉(zhuǎn)換定義為枚舉類型,如:
public enum IplImageDepth :int {U8=8,…}
public enum ColorConversion :int{...Bgr2Gray=6,Gray2Bgr=8,…}
需要用到OpenCV庫的函數(shù)有下面這些,使用DllImport引入這些函數(shù),并自主擴(kuò)展成C#的方法:
顏色空間轉(zhuǎn)換代碼:
[DllImport("opencv_imgproc248", CallingConvention=CallingConvention.Cdecl)]
internal static extern void cvCvtColor(ArrayLike src, ArrayLike dst, ColorConversion colorCode);
圖像高斯平滑代碼:
[DllImport("opencv_imgproc248", CallingConvention=CallingConvention.Cdecl)]
internal static extern void cvSmooth(ArrayLike src,ArrayLike dst,SmoothMethod method,int size1,int size2,double sigma1,double sigma2);
圖像邊緣檢測(cè)代碼:
[DllImport("opencv_imgproc248", CallingConvention=CallingConvention.Cdecl)]
internal static extern void cvCanny(ArrayLike image, ArrayLike edges, double threshold1, double threshold2, int apertureSize);
Hough變換圓形檢測(cè)代碼:
[DllImport("opencv_imgproc248", CallingConvention=CallingConvention.Cdecl)]
internal static extern Seq cvHoughCircles(ArrayLike image, CVHandle circle_storage, HoughCirclesMethod method, double dp, double min_dist, double param1, double param2, int min_radius, int max_radius);
如圖3是一張測(cè)雪板實(shí)景照片,這張受太陽光影響的圖像出現(xiàn)了明顯的明亮和陰影分界,加大圓檢測(cè)的難度。
圖3 測(cè)雪板實(shí)景原始照片
因此先截取圓形測(cè)雪點(diǎn)附近區(qū)域,然后進(jìn)行圖像平滑處理,為后面的圓檢測(cè)排除無關(guān)干擾,同時(shí)縮小處理范圍以利于節(jié)省系統(tǒng)資源開支。圖像高斯平滑處理關(guān)鍵代碼:
private IplImage SmoothImage(IplImage originalImage)
{
IplImage image=originalImage.GetSubRect(new Rect(190, 150, 200, 200));
∥截取測(cè)雪點(diǎn)附近200×200像素區(qū)域
Size resolution=image.Size;
IplImage ret=new IplImage(resolution, IplImageDepth.U8, 1);
CvtColor(image, ret, ColorConversion.Bgr2Gray);
int passes=Passes;
∥平滑重復(fù)次數(shù),此處的Passes為來自指定參數(shù)配置
int x=XKernel;
∥一般為卷積核的水平方向直徑(選擇高斯平滑時(shí)必須為奇數(shù)),此處的Xkernel來自實(shí)際應(yīng)用的指定參數(shù)配置
int y=YKernel;
∥在簡單/非尺度變換的高斯模糊的情況下,如果y的值為零,則表示其被設(shè)定為x,此處的YKernel為來自指定參數(shù)配置
for (int i=0; i < passes; i++)
{OpenCV.Smooth(ret, ret, SmoothMethod.Gaussian, x, y, 0, 0); }
return ret;
}
實(shí)際平滑后的輸出圖像如圖4。
圖4 高斯平滑處理好的圖像
接著對(duì)高斯平滑后的圖像進(jìn)行邊緣檢測(cè),圖像邊緣檢測(cè)的關(guān)鍵代碼如下:
IplImage canny=new IplImage(resolution, IplImageDepth.U8, 1);
OpenCV.Canny(smoothResult, canny, Math.Max(cannyThreshold/2, 1), cannyThreshold, 3);
∥其中smoothResult為圖像平滑處理返回的結(jié)果,cannyThreshold為來自指定參數(shù)的邊緣檢測(cè)閾值
圖5a為對(duì)指定區(qū)域進(jìn)行邊緣檢測(cè)的結(jié)果,圖5b圖為整幅圖像進(jìn)行邊緣檢測(cè)的結(jié)果,在這一步中可以很明顯可以看出,圖5b中的一些無光邊緣會(huì)為后面的圓檢測(cè)帶來很大的干擾。因此,在這個(gè)實(shí)際應(yīng)用中截取指定區(qū)域的圖像顯得尤為重要。
(a)指定區(qū)域的邊緣檢測(cè)結(jié)果;(b)整幅圖像的邊緣檢測(cè)結(jié)果圖5 不同區(qū)域的邊緣檢測(cè)結(jié)果
將OpenCV中的圓檢測(cè)C++代碼實(shí)現(xiàn)成C#代碼:
public static Seq HoughCircles(ArrayLike image, CVHandle circleStorage, HoughCirclesMethod method, double dp, double minDist, double param1, double param2, int minRadius, int maxRadius)
{
var circles=cvHoughCircles(image, circleStorage, method, dp, minDist, param1, param2, minRadius, maxRadius);
if (circles.IsInvalid) return null;
circles.SetOwnerStorage((MemoryStorage)circleStorage);
return circles;
}
然后就可以在.Net Framework框架下輕松調(diào)用這個(gè)函數(shù)檢測(cè)圖像中的圓:
public static Seq DetectCircles(IplImage pImage, HoughDetectionSettings pSettings)
{
Seq ret;
try{
MemStorage storage=new MemStorage(0);
ret=OpenCV.HoughCircles(pImage, storage, HoughCirclesMethod.Gradient,dp,minDistance,cannyThreshold,accuThreshold,minRadius,maxRadius);
}catch{throw;}
return ret;
}
最后,把這些圓從原圖中標(biāo)識(shí)出來:
public static void DrawCircles(IplImage pImage, Seq circles)
{
try{
int count=circles.Count;
for (int i=0; i < count; i++)
{
float[] p=new float[3];
Marshal.Copy(pCircles.GetElement(i), p, 0, 3);
CV.Circle(pImage,new Point((int)Math.Round(p[0]), (int)Math.Round(p[1])), 3, new Scalar(0, 255, 0),-1,LineFlags.Connected8, 0);
CV.Circle(pImage, new Point((int)Math.Round(p[0]), (int)Math.Round(p[1])), (int)Math.Round(p[2]), new Scalar(255, 0, 0), 3, LineFlags.Connected8, 0);
}
}catch{throw;}
}
如圖6所示,為最終實(shí)際測(cè)雪點(diǎn)的圓檢測(cè)結(jié)果。
圖6 實(shí)際的圓檢測(cè)結(jié)果
有了這個(gè)圓形關(guān)鍵區(qū)域,一般就可以認(rèn)為不存在積雪。但是也可能下了薄薄的一層雪卻還保留著這個(gè)圓,因此還要進(jìn)一步對(duì)這個(gè)圓形區(qū)
域進(jìn)行色彩識(shí)別等。進(jìn)行色彩識(shí)別需要對(duì)圖像進(jìn)行色彩空間轉(zhuǎn)換、二值化處理、膨脹腐蝕處理等[3]。最終明確測(cè)雪點(diǎn)上是否覆蓋了雪,從而協(xié)助輔助判斷自動(dòng)雪深觀測(cè)儀當(dāng)前實(shí)時(shí)數(shù)據(jù)是否為疑誤數(shù)據(jù)。
隨著自動(dòng)雪深觀測(cè)站和雪深實(shí)景監(jiān)控的大量部署,應(yīng)當(dāng)充分發(fā)揮雪深實(shí)景監(jiān)控的作用從而確保雪深數(shù)據(jù)準(zhǔn)確可靠。為了達(dá)到這個(gè)目的,本文對(duì)基于OpenCV實(shí)現(xiàn)對(duì)測(cè)雪點(diǎn)的智能識(shí)別的關(guān)鍵方法進(jìn)行了詳細(xì)分析,利用OpenCV中的多種圖像處理功能輔助協(xié)助處理雪深觀測(cè)站的疑誤數(shù)據(jù)。但現(xiàn)有的圖像處理算法仍有不足之處,在較為復(fù)雜的自然環(huán)境下,由于光線、遮擋等復(fù)雜情況都會(huì)對(duì)圖像處理結(jié)果產(chǎn)生影響。因此,提高識(shí)別的準(zhǔn)確率是應(yīng)用中的難點(diǎn),需要對(duì)OpenCV中算法做進(jìn)一步研究和擴(kuò)展。
[1] 于仕琪,劉瑞禎.學(xué)習(xí)OpenCV(中文版)[M].北京:清華大學(xué)出版社,2009.
[2] 方玫,喻擎蒼,李華強(qiáng),等.C++Builder下基于OpenCV的數(shù)字圖像的處理[J].計(jì)算機(jī)工程與設(shè)計(jì),2008,29(4):882-884.
[3] 劉潔,馮貴玉,張汗靈.一種圖像處理和計(jì)算機(jī)視覺的開發(fā)工具[J].計(jì)算機(jī)仿真,2006,23(11):305-307.
2016-03-28