




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第5章圖像處理第5章圖像處理1《學(xué)習(xí)OpenCV》第5章-圖像處理課件2本章各小節(jié)目錄綜述平滑處理圖像形態(tài)學(xué)漫水填充算法尺寸調(diào)整圖像金字塔閾值化練習(xí)本章各小節(jié)目錄綜述3綜述到這里,我們已經(jīng)掌握了關(guān)于圖像處理的所有基礎(chǔ)知識(shí)。我們了解了OpenCV庫(kù)的結(jié)構(gòu),也知道了通常用來表示圖像的基本數(shù)據(jù)結(jié)構(gòu)。通過熟悉HighGUI接口,我們可以運(yùn)行程序并將結(jié)果顯示在屏幕上。掌握了這些用來控制圖像結(jié)構(gòu)的基本方法,我們就可以學(xué)習(xí)更復(fù)雜的圖像處理方法了。現(xiàn)在,我們來繼續(xù)學(xué)習(xí)高級(jí)的處理方法,即把圖像以“圖像”的方式來處理,而不是由顏色值(或灰度值)組成的數(shù)組。在提到“圖像處理”時(shí),它的意思是:使用圖像結(jié)構(gòu)中所定義的高層處理方法來完成特定任務(wù),這些任務(wù)是圖形和視覺范疇的任務(wù)。綜述到這里,我們已經(jīng)掌握了關(guān)于圖像處理的所有基礎(chǔ)知識(shí)。我們了4平滑處理“平滑處理”也稱“模糊處理”(blurring),是一項(xiàng)簡(jiǎn)單且使用頻率很高的圖像處理方法。平滑處理的用途有很多,但最常見的是用來減少圖像上的噪聲或者失真。降低圖像分辨率時(shí),平滑處理是很重要的(在本章的“圖像金字塔”部分會(huì)詳細(xì)介紹這一點(diǎn))。目前OpenCV可以提供五種不同的平滑操作方法,所有操作都由cvSmooth函數(shù)實(shí)現(xiàn),該函數(shù)可以將用戶所期望的平滑方式作為參數(shù)。平滑處理“平滑處理”也稱“模糊處理”(blurring),是5voidcvSmooth(constCvArr*src,CvArr*dst,intsmoothtype=CV_GAUSSIAN,intparam1=3,intparam2=0,doubleparam3=0,doubleparam4=0);src和dst分別是平滑操作的輸入圖像和結(jié)果,cvSmooth()函數(shù)包含4個(gè)參數(shù),param1,param2,param3和param4。這些參數(shù)的含義取決于smoothtype的值,這些值可能是表5.1中列出的任何一個(gè)。(請(qǐng)注意,有些操作不支持inplace方式的輸入。inplace方式意味著輸voidcvSmooth(6入圖像與結(jié)果圖像是同一個(gè)圖像。)表5-1:平滑操作的各種類型平滑類型名稱支持No輸入類型輸出類型簡(jiǎn)要介紹CV_BLUR簡(jiǎn)單模糊是1,38u,32f8u,32f對(duì)每個(gè)像素param1×param2鄰域求和,并做縮放1/(param1param2)CV_BLUR_NO_SCALE簡(jiǎn)單無縮放變換的模糊否18u16s(占8u的資源)或32f(占32f的資源大小)對(duì)每個(gè)像素的param1×param2鄰域求和CV_MEDIAN中值模糊否1,38u8u對(duì)圖像進(jìn)行核大小為parma1×param2的中值濾波CV_GAUSSIAN高斯模糊是1,38u,32f8u(占8u的資源)或32f(占32f的資源)對(duì)圖像進(jìn)行核大小為param1×param2的高斯卷積CV_BILATERAL雙邊濾波否1,38u8u應(yīng)用雙線性3×3濾波,顏色sigma=param1,空間sigma=param2入圖像與結(jié)果圖像是同一個(gè)圖像。)平滑類型名稱支持No輸入類型7圖5.1CV_BLUR所例舉的simpleblur是最簡(jiǎn)單的一項(xiàng)操作。輸出圖像的每一個(gè)像素是窗口中輸入圖像對(duì)應(yīng)像素的簡(jiǎn)單平均值。simpleblur支持1~4個(gè)圖像通道,可以處理8位圖像或者32位的浮點(diǎn)圖像。圖5-1:簡(jiǎn)單圖像平滑處理:左邊為輸入圖像,右邊為結(jié)果圖像圖5.1CV_BLUR所例舉的simpleblur是最簡(jiǎn)單8不是所有的模糊操作的輸入和結(jié)果圖像類型都相同,CV_BLUR_NO_SCALE(不縮放比例而進(jìn)行模糊處理)與simpleblur本質(zhì)上是相同的,但并沒有計(jì)算其平均值的操作。因此,輸入圖像和結(jié)果圖像必須有不同的數(shù)值精度,才能保證模糊操作不會(huì)導(dǎo)致錯(cuò)誤溢出。不縮放比例的simpleblur支持8位的輸入圖像,結(jié)果圖像的數(shù)據(jù)類型必須是IPL_DEPTH_16S(CV_16S)或IPL_DEPTH_32S(CV_32S)。同樣的操作也可以在32位浮點(diǎn)圖像上進(jìn)行,結(jié)果圖像也應(yīng)該是32位浮點(diǎn)類型。簡(jiǎn)單無縮放變換的模糊不支持inplace方式:輸入圖像與結(jié)果圖像必須不同。(在8位和16位情況下,很明顯不能用inplace方式;用32位圖像時(shí),也保持這一規(guī)定。)用戶選擇不縮放比例的模糊操作是因?yàn)槠浔瓤s放比例的模糊操作要快一些。不是所有的模糊操作的輸入和結(jié)果圖像類型都相同,CV_BLUR9中值濾波器(CV_MEDIAN)[Bardyn84]將中心要素的正方形鄰域內(nèi)的每個(gè)像素值用中間像素值(不是平均像素值)替換,它可以用來處理單個(gè)通道、三個(gè)通道或者四個(gè)通道8位的圖像,但不可以inplace操作。中值濾波的結(jié)果見圖5-2?;谄骄惴ǖ膕impleblur對(duì)噪聲圖像特別是有大的孤立點(diǎn)(有時(shí)被稱為“鏡頭噪聲”)的圖像非常敏感,即使有極少數(shù)量點(diǎn)存在較大差異也會(huì)導(dǎo)致平均值的明顯波動(dòng),因此中值濾波可以通過選擇中間值避免這些點(diǎn)的影響。中值濾波器(CV_MEDIAN)[Bardyn84]將中心要10下一個(gè)平滑濾波器是Gaussianfilter(CV_GAUSSIAN),雖然它不是最快的,但它是最有用的濾波器。高斯濾波用卷積核與輸入圖像的每個(gè)點(diǎn)進(jìn)行卷積,最終計(jì)算結(jié)果之和作為輸出圖像的像素值。對(duì)于高斯模糊(圖5-3),前兩個(gè)參數(shù)代表濾波器窗口的寬度和高度,可選擇的第三個(gè)參數(shù)代表卷積核的sigma值(是最大寬度的四分之一)。如果第?個(gè)參數(shù)未指定,系統(tǒng)將會(huì)根據(jù)窗口尺寸通過下面的方程來自動(dòng)確定高斯核的各個(gè)參數(shù)。圖5-3:對(duì)一維像素?cái)?shù)組進(jìn)行高斯模糊參數(shù)1:濾波器寬度參數(shù)2:濾波器高度下一個(gè)平滑濾波器是Gaussianfilter(CV_GA11如果用戶希望高斯核不對(duì)稱,那么可以引入第四個(gè)參數(shù)。這樣,第三個(gè)和第四個(gè)參數(shù)分別為水平方向和垂直方向的sigma值。如果第三個(gè)和第四個(gè)參數(shù)已經(jīng)給出,但是前兩個(gè)參數(shù)被設(shè)為0,那么窗口的尺寸會(huì)根據(jù)sigma值自動(dòng)確定。高斯濾波的OpenCV的實(shí)現(xiàn)還為幾個(gè)常見的核提供了更高的性能優(yōu)化。具有標(biāo)準(zhǔn)sigma值的3×3,5×5和7×7比其他核具有更優(yōu)的性能。高斯模糊支持單個(gè)通道或者三個(gè)通道的8位或32位的浮點(diǎn)格式圖像,可以進(jìn)行inplace方式操作。高斯模糊的效果見圖5-4。如果用戶希望高斯核不對(duì)稱,那么可以引入第四個(gè)參數(shù)。這樣,第三12OpenCV支持的第五個(gè)也是最后一個(gè)平滑操作被稱作雙邊濾波(bilateralfiltering)[Tomasi98],舉例見圖5-5。雙邊濾波是“邊緣保留濾波”的圖像分析方法中的一種。將它與高斯平滑對(duì)比后會(huì)更容易理解。進(jìn)行高斯濾波的????是真實(shí)在空間內(nèi)的像素是緩慢變化的,因此臨近點(diǎn)的像素變化不會(huì)太明顯。但是隨機(jī)??個(gè)點(diǎn)就可能形成很大的像素差(也就是說空間噪聲點(diǎn)不是相互聯(lián)系的)。正是??這一點(diǎn),高斯濾波在保留信號(hào)的條件下減少噪聲。遺憾的是,這種方法在接近??處就無效了,在那兒你不希望像素與相鄰像素相關(guān)。因此,高斯濾波會(huì)磨平邊??。而雙邊濾波能夠提供一種不會(huì)將邊緣的平滑掉的方法,但作為代價(jià),需要更多??時(shí)間。與高斯濾波類似,雙邊濾波會(huì)依據(jù)每個(gè)像素及其鄰域OpenCV支持的第五個(gè)也是最后一個(gè)平滑操作被稱作雙邊濾波(13構(gòu)造一個(gè)加權(quán)平均值,加權(quán)計(jì)算包括兩個(gè)部分,其中第一部分加權(quán)方式與高斯平滑中的相同,第二部分也屬于高斯加權(quán),但不是基于中心像素點(diǎn)與其他像素點(diǎn)的空間距離之上的加權(quán),而是基于其他像素與中心像素的亮度差值的加權(quán)??梢詫㈦p邊濾波視為高斯平滑,對(duì)相似的像素賦予較高的權(quán)重,不相似的像素賦予較小的權(quán)重。這種濾波的典型??就是使處理過的圖像看上去像是一幅源圖的水彩畫,可用于圖像的分割。雙邊濾波含有兩個(gè)參數(shù)。第一個(gè)參數(shù)代表空域中使用的高斯核的寬度,和高斯濾波的sigma參數(shù)類似。第二個(gè)參數(shù)代表顏色域內(nèi)高斯核的寬度。第二個(gè)參數(shù)越大,表明待濾波的強(qiáng)度(或顏色)范圍越大(因此不連續(xù)的程度越高,以便保留)。構(gòu)造一個(gè)加權(quán)平均值,加權(quán)計(jì)算包括兩個(gè)部分,其中第一部分加權(quán)方14圖像形態(tài)學(xué)OpenCV為進(jìn)行圖像的形態(tài)學(xué)變換[Serra83]提供了快速、方便的函數(shù)?;镜男螒B(tài)轉(zhuǎn)換是膨脹與腐蝕,它們能實(shí)現(xiàn)多種功能:例如消除噪聲、分割出獨(dú)立的圖像元素以及在圖像中連接相鄰的元素。形態(tài)學(xué)也常被用于尋找圖像中的明顯的極大值區(qū)域或極小值區(qū)域以及求出圖像的梯度。圖像形態(tài)學(xué)OpenCV為進(jìn)行圖像的形態(tài)學(xué)變換[Serra8315膨脹和腐蝕膨脹是指將一些圖像(或圖像中的一部分區(qū)域,稱之為A)與核(稱之為B)進(jìn)行卷積。核可以是任何的形狀或大小,它擁有一個(gè)單獨(dú)定義出來的參考點(diǎn)(anchorpoint)。多數(shù)情況下,核是一個(gè)小的中間帶有參考點(diǎn)的實(shí)心正方形或圓盤。核可以視為模板或掩碼,膨脹是求局部最大值的操作。核B與圖像卷積,即計(jì)算核B覆蓋的區(qū)域的像素點(diǎn)最大值,并把這個(gè)最大值賦值給參考點(diǎn)指定的像素。這樣就會(huì)使圖像中的高亮區(qū)域逐漸增長(zhǎng),如圖5-6所示。這樣的增長(zhǎng)就是“膨脹操作”的初衷。圖5-6:形態(tài)學(xué)膨脹:在核B下取最大像素值膨脹和腐蝕圖5-6:形態(tài)學(xué)膨脹:在核B下取最大像素值16腐蝕是膨脹的反操作。腐蝕操作要計(jì)算核區(qū)域像素的最小值。腐蝕可以通過下面的算法生成一個(gè)新的圖像:當(dāng)核B與圖像卷積時(shí),計(jì)算被B覆蓋區(qū)域的最小像素值,并把這個(gè)值放到參考點(diǎn)上。腐蝕后的圖像如圖5-7所示。一般來說,膨脹擴(kuò)展了區(qū)域A,而腐蝕縮小了區(qū)域A。此圖5-7:形態(tài)腐蝕:在核B之下取最小像素值腐蝕是膨脹的反操作。腐蝕操作要計(jì)算核區(qū)域像素的最小值。腐蝕可17外,膨脹可以填補(bǔ)凹洞,腐蝕能夠消除細(xì)的凸起。當(dāng)然,準(zhǔn)確的效果將取決于核,但當(dāng)使用凸核時(shí)前面的說法一般是對(duì)的。在OpenCV,我們利用cvErode()和cvDilate()函數(shù)實(shí)現(xiàn)上述變換。voidcvErode(IplImage*src,IplImage*dst,IplConvKernel*B=NULL,intiterations=1);voidcvDilate(IplImage*src,IplImage*dst,IplConvKernel*B=NULL,intiterations=1);外,膨脹可以填補(bǔ)凹洞,腐蝕能夠消除細(xì)的凸起。當(dāng)然,準(zhǔn)確的效果18cvErode()和cvDilate()都有源圖像和目標(biāo)圖像參數(shù),它們都支持“in-place”操作(源圖像和目標(biāo)圖像是同一個(gè)圖像)。第三個(gè)參數(shù)是核,默認(rèn)值為NULL。當(dāng)為空時(shí),所使用的是參考點(diǎn)位于中心的3×3核(我們將簡(jiǎn)單討論如何構(gòu)造核)。最后,第四個(gè)參數(shù)是迭代的次數(shù)。如果未將它設(shè)置為默認(rèn)值(1),將在一次函數(shù)的調(diào)用中執(zhí)行多次操作。腐蝕操作的結(jié)果如圖5-8所示,膨脹操作的結(jié)果如圖5-9所示。腐蝕操作通常是用來消除圖像中“斑點(diǎn)”噪聲。腐蝕可以將斑點(diǎn)腐蝕掉,且能確保圖像內(nèi)的較大區(qū)域依然存在。在試圖找到連通分支(即具有相似顏色或強(qiáng)度的像素點(diǎn)的大塊的互相分離的區(qū)域)時(shí)通常使用膨脹操作。因?yàn)樵诖蠖鄶?shù)情況下一個(gè)大區(qū)域可能被噪聲、陰影等類似的東西分割成多個(gè)部分,而一次輕微的膨脹又將使這些部分“融合”在一起。cvErode()和cvDilate()都有源圖像和目標(biāo)圖像19綜上所述:當(dāng)OpenCV執(zhí)行cvErode()函數(shù)時(shí),將某點(diǎn)p的像素值設(shè)為與p對(duì)應(yīng)的核覆蓋下所有點(diǎn)中的最小值,同樣的,對(duì)于執(zhí)行膨脹操作時(shí),將取最小值換為取最大值:大家可能會(huì)想,既然之前的算法描述已經(jīng)能解釋清楚,為什么還需要引入一個(gè)復(fù)雜的公式呢?實(shí)際上,有些讀者喜歡這樣的公式,更重要的是,公式可以闡明一些定性描述表達(dá)不清楚的一般性問題。我們能夠注意到,如果圖像不是二值的,那么膨脹和腐蝕操作起到的作用不是很明顯。再看一看圖5-8和圖5-9,分別展示了對(duì)兩個(gè)圖像進(jìn)行腐蝕和膨脹操作的效果。綜上所述:當(dāng)OpenCV執(zhí)行cvErode()函數(shù)時(shí),將某點(diǎn)20圖5-8:腐蝕的結(jié)果或者“最小化”操作,亮的區(qū)域被隔離并且縮小圖5-8:腐蝕的結(jié)果或者“最小化”操作,亮的區(qū)域被隔離并且縮21
圖5-9:膨脹的“最大化”操作:亮的區(qū)域得到了擴(kuò)展和連接圖5-9:膨脹的“最大化”操作:亮的區(qū)域得到了擴(kuò)展和連接22自定義核你不必局限于選擇3×3方形的核??梢詣?chuàng)建自定義的IplConvKernel核(即我們之前提到的“核B”)。這樣的核由cvCreateStructuringElementEx()函數(shù)創(chuàng)建,由cvReleaseStructuringElement()函數(shù)釋放。IplConvKernel*cvCreateStructuringElementEx(intcols,introws,intanchor_x,intanchor_y,intshape,int*values=NULL);自定義核23voidcvReleaseStructuringElement(IplConvKernel**element);形態(tài)核與卷積核不同,不需要任何的數(shù)值填充核。當(dāng)核在圖像上移動(dòng)時(shí),核的元素只需簡(jiǎn)單標(biāo)明應(yīng)該在哪個(gè)范圍里計(jì)算最大值或最小值。參考點(diǎn)指定核與源圖像的位置關(guān)系,同時(shí)也鎖定了計(jì)算結(jié)果在目標(biāo)圖像中的位置。當(dāng)構(gòu)造核時(shí),行與列確定了所構(gòu)造的矩形大?。ň匦蝺?nèi)含有結(jié)構(gòu)元素),下兩個(gè)參數(shù)anchor_x和anchor_y,是核的封閉矩形內(nèi)參考點(diǎn)的橫縱坐標(biāo)(x,y)。第五個(gè)參數(shù),形狀shape可以取表5-2中所列的值。如果使用CV_SHAPE_CUSTOM,那么使用整數(shù)向量value在封閉矩形內(nèi)定義核的形狀。使用光柵掃描法讀取向量,使每個(gè)元素代表封閉矩形中的不同像素。所有非零值指定在核中對(duì)應(yīng)的各個(gè)像素點(diǎn)。如果值為空,通常會(huì)構(gòu)造一個(gè)所有值為非空的矩形核。voidcvReleaseStructuringEleme24表5-2:IplConvKernel的形狀取值形狀值含義CV_SHAPE_RECT核是矩形CV_SHAPE_CROSS核是十字交叉形CV_SHAPE_ELLIPSE核是橢圓形CV_SHAPE_CUSTOM核是用戶自定義的值表5-2:IplConvKernel的形狀取值形狀值含義CV25更通用的形態(tài)學(xué)在處理布爾圖像和圖像掩碼時(shí),基本的腐蝕和膨脹操作通常是足夠的。然而,在處理灰度或彩色圖像時(shí),往往需要一些額外的操作。更通用的cvMorphologyEx()函數(shù)提供了更多有用的操作。voidcvMorphologyEx(constCvArr*src,CvArr*dst,CvArr*temp,IplConvKernel*element,intoperation,intiterations=1);更通用的形態(tài)學(xué)26除了以往操作中使用過的參數(shù):如src,dst,element和iterations外,cvMorphologyEx()函數(shù)增加了兩個(gè)新的參數(shù)。第一個(gè)是temp數(shù)組,它在一些操作可能會(huì)用到(參見表5-3)。使用該數(shù)組時(shí),它應(yīng)與源圖像同樣大小。第二個(gè)參數(shù)operation很有趣,它指定形態(tài)學(xué)操作的方法。表5-3:cvMorphologyEx()操作選項(xiàng)操作名稱形態(tài)學(xué)是否需要臨時(shí)圖像CV_MOP_OPEN開運(yùn)算否CV_MOP_CLOSE閉運(yùn)算否CV_MOP_GRADIENT形態(tài)梯度總是CV_MOP_TOPHOT“禮帽”in-place情況下(src=dst)需要CV_MOP_BLACKHAT“黑帽”in-place情況下(src=dst)需要除了以往操作中使用過的參數(shù):如src,dst,eleme27開運(yùn)算與閉運(yùn)算表5-3中的前兩個(gè)操作開運(yùn)算和閉運(yùn)算包含腐蝕和膨脹操作。在開運(yùn)算的情況下,我們首先將其腐蝕然后再膨脹(圖5-10)。開運(yùn)算通??梢杂脕斫y(tǒng)計(jì)二值圖像中的區(qū)域數(shù)。若已將顯微鏡載玻片上觀察到的細(xì)胞圖像作了閾值化處理,可以使用開運(yùn)算將相鄰的細(xì)胞分離開來,然后再計(jì)算圖像中的區(qū)域(細(xì)胞)數(shù)目。在閉圖5-10:形態(tài)的開運(yùn)算(向上的孤立點(diǎn)被消除)開運(yùn)算與閉運(yùn)算圖5-10:形態(tài)的開運(yùn)算(向上的孤立點(diǎn)被消除)28運(yùn)算的情況下,我們首先將其膨脹然后再腐蝕(圖5-12)。在大多數(shù)好的連通區(qū)域分析算法中,都會(huì)用到閉運(yùn)算來去除噪聲引起區(qū)域。對(duì)于連通區(qū)域分析,通常先采用腐蝕或閉運(yùn)算來消除純粹由噪聲引起的部分,然后用開運(yùn)算來連接鄰近的區(qū)域。(注意,雖然使用開運(yùn)算或閉運(yùn)算的結(jié)果與使用腐蝕和膨脹的結(jié)果類似,但這兩個(gè)新的操作能更精確地保存源圖像連接的區(qū)域。)圖5-12:形態(tài)閉運(yùn)算的操作(消除低亮度值的孤立點(diǎn))運(yùn)算的情況下,我們首先將其膨脹然后再腐蝕(圖5-12)。在大29開運(yùn)算和閉運(yùn)算操作幾乎都是“保留區(qū)域”形式的:最顯著的效果是,閉運(yùn)算消除了低于其鄰近點(diǎn)的孤立點(diǎn),而開運(yùn)算是消除高于其鄰近點(diǎn)的孤立點(diǎn)。開運(yùn)算的結(jié)果如圖5-11所示,閉運(yùn)算的結(jié)果如圖5-13所示。開運(yùn)算和閉運(yùn)算操作幾乎都是“保留區(qū)域”形式的:最顯著的效果是30開運(yùn)算和閉運(yùn)算操作幾乎都是“面積保持”形式的:最顯著的效果是,閉運(yùn)算消除了低于其鄰近點(diǎn)的孤立點(diǎn),而開運(yùn)算是消除高于其鄰近點(diǎn)的孤立點(diǎn)。開運(yùn)算的結(jié)果如圖5-11所示,閉運(yùn)算的結(jié)果如圖5-13所示。關(guān)于開運(yùn)算和閉運(yùn)算,最后一點(diǎn)需要說明的是iterations參數(shù)的意思。您可能會(huì)認(rèn)為閉操作執(zhí)行兩次,相當(dāng)于執(zhí)行膨脹-腐蝕-膨脹-腐蝕。但事實(shí)上,這并不是必要的。真正需要的(并且所能得到的)是膨脹-膨脹-腐蝕-腐蝕這樣的過程。通過這種方式,不僅是單一的孤立點(diǎn)會(huì)消失,而且鄰近的孤離點(diǎn)群也會(huì)消失。開運(yùn)算和閉運(yùn)算操作幾乎都是“面積保持”形式的:最顯著的效果是31形態(tài)學(xué)梯度下一個(gè)可用的操作是形態(tài)學(xué)梯度。在這里我們先給出其公式,然后再解釋公式的含義:gradient(src)=dilate(src)–erode(src)對(duì)二值圖像進(jìn)行這一操作可以將團(tuán)塊(blob)的邊緣突出出來。圖5-14解釋了這一操作,在測(cè)試圖像上進(jìn)行操作的效果如圖5-15所示。圖5-14:形態(tài)梯度被應(yīng)用于灰度圖(正如所料,在灰度值變化最劇烈的區(qū)域得到的結(jié)果數(shù)值最大)形態(tài)學(xué)梯度圖5-14:形態(tài)梯度被應(yīng)用于灰度圖(正如所料,在灰32觀察對(duì)灰度圖像的處理結(jié)果,可以獲知形態(tài)學(xué)梯度操作能描述圖像亮度變化的劇烈程度;這就是為什么把其稱為“形態(tài)學(xué)梯度”的原因。當(dāng)我們想突出高亮區(qū)域的外圍時(shí),通??墒褂眯螒B(tài)學(xué)梯度,這樣我們可以把高亮的看成一個(gè)整體(或物體的一整部分)。因?yàn)閺脑瓍^(qū)域的膨脹中減去了原區(qū)域的收縮,所以留下了完整的外圍邊緣。這與計(jì)算梯度有所不同,梯度一般不能獲得物體的外圍邊緣。觀察對(duì)灰度圖像的處理結(jié)果,可以獲知形態(tài)學(xué)梯度操作能描述圖像亮33禮帽和黑帽最后兩個(gè)操作被稱為禮帽(TopHat)和黑帽變換(BlackHat)[Meyer78]。這些操作分別用于分離比鄰近的點(diǎn)亮或暗的一些斑塊。當(dāng)試圖孤立的部分相對(duì)于其鄰近的部分有亮度變化時(shí),就可以使用這些方法。例如常用與處理有機(jī)組織或細(xì)胞的顯微鏡圖像。這是兩個(gè)操作都是基本的操作組合,定義如下:TopHat(src)=src-open(src)BlackHat(src)=close(src)-src可以看出,禮帽操作從A中減去了A的開運(yùn)算。開運(yùn)算帶來的結(jié)果是放大裂縫或局部低亮度區(qū)域,因此,從A中減去open(A)可以突出比A周圍的區(qū)域更明亮的區(qū)域,并跟核的大小相關(guān)(參見圖5-16);相反地,黑帽操禮帽和黑帽34作突出比A的周圍的區(qū)域黑暗的區(qū)域(圖5-17)。在本章討論的所有形態(tài)操作的結(jié)果均可參見圖5-18。圖5-17:形態(tài)學(xué)“黑帽”操作的效果(黑色“洞”被分割出)作突出比A的周圍的區(qū)域黑暗的區(qū)域(圖5-17)。在本章討論的35
圖5-18:所有形態(tài)學(xué)算子操作的效果匯總圖5-18:所有形態(tài)學(xué)算子操作的效果匯總36漫水填充算法漫水填充(FloodFill)[Heckbert00;Shaw04;Vandevenne04]是一個(gè)非常有用的功能,它經(jīng)常被用來標(biāo)記或分離圖像的一部分以便對(duì)其進(jìn)行進(jìn)一步處理或分析。漫水填充也可以用來從輸入圖像獲取掩碼區(qū)域,掩碼會(huì)加速處理過程,或只處理掩碼指定的像素點(diǎn)。cvFloodFill函數(shù)本身也包含一個(gè)可選的掩碼參數(shù),用來進(jìn)一步控制哪些區(qū)域?qū)⒈惶畛漕伾ɡ绠?dāng)對(duì)同一圖像進(jìn)行多次填充時(shí))。在OpenCV里,漫水填充是填充算法中最通用的方法,漫水填充算法漫水填充(FloodFill)[Heckber37也許你看到這里已經(jīng)將其與典型的計(jì)算機(jī)繪圖程序聯(lián)系起來。對(duì)于兩種程序來說,都必須在圖像上選擇一個(gè)種子點(diǎn),然后把鄰近區(qū)域所有相似點(diǎn)填充上同樣的顏色,不同的是不一定將所有的鄰近像素點(diǎn)都被染成同一顏色,漫水填充操作的結(jié)果總是某個(gè)連續(xù)的區(qū)域。當(dāng)鄰近像素點(diǎn)位于給定的范圍(從loDiff到upDiff)內(nèi)或在原始seedPoint像素值范圍內(nèi)時(shí),cvFloodFill()函數(shù)將為這個(gè)點(diǎn)涂上顏色。可選參數(shù)mask也可以用來控制漫水法填充。該填充方法的函數(shù)原型如下所示:voidcvFloodFill(IplImage*img,CvPointseedPoint,CvScalarnewVal,CvScalarloDiff=cvScalarAll(0),CvScalarupDiff=cvScalarAll(0),CvConnectedComp*comp=NULL,intflags=4,CvArr*mask=NULL);也許你看到這里已經(jīng)將其與典型的計(jì)算機(jī)繪圖程序聯(lián)系起來。對(duì)于兩38img參數(shù)代表輸入圖像,該圖像可以是8位或浮點(diǎn)類型的單通道或三通道圖像。漫水法填充從點(diǎn)seedPoint開始,newVal是像素點(diǎn)被染色的值。如果一個(gè)像素點(diǎn)的值不低于被染色的相鄰點(diǎn)減去loDiff且不高于其加上upDiff,那么該像素點(diǎn)就會(huì)被染色。如果flags參數(shù)包含CV_FLOODFILL_FIXED_RANGE,這時(shí)每個(gè)像素點(diǎn)都將與種子點(diǎn)而不是相鄰點(diǎn)相比較。如果comp不是NULL,那么該CvConnectedComp結(jié)構(gòu)將被設(shè)置為被填充區(qū)域的統(tǒng)計(jì)屬性。flags參數(shù)(下文會(huì)有簡(jiǎn)短論述)有些復(fù)雜,這些參數(shù)決定填充的連通性、相關(guān)性、是否只填充掩碼區(qū)域及用來填充的值。我們第一個(gè)漫水填充例子見圖5-19。img參數(shù)代表輸入圖像,該圖像可以是8位或浮點(diǎn)類型的單通道或39這里mask參數(shù)所代表的掩碼既可以作為cvFloodFill()函數(shù)的輸入值(此時(shí)它控制可以被填充的區(qū)域),也可以作為cvFloodFill()函數(shù)的輸出值(此時(shí)它指已經(jīng)被填充圖5-19:漫水填充的效果(上方圖像用灰色填充,下方圖像用白色填充),從位于兩個(gè)圖像中心旁的黑色圓形區(qū)域開始填充;此處hiDiff與loDiff參數(shù)均設(shè)為7.0圖5-19:漫水填充的效果(上方圖像用灰色填充,下方圖像用白40的區(qū)域)。如果mask非空,那么它必須是一個(gè)單通道、8位、像素寬度和高度均比源圖像大兩倍的圖像(這是為了使內(nèi)部運(yùn)算更簡(jiǎn)單快速)。mask圖像的像素(x+1,y+1)與源圖像的像素(x,y)相對(duì)應(yīng)。注意,cvFloodFill()不會(huì)覆蓋mask的非0像素點(diǎn),因此如果不希望mask阻礙填充操作時(shí),將其中元素設(shè)為0。源圖像img和掩碼圖像mask均可以用漫水填充來染色。注意:如果漫水填充的掩碼不為空,那么要用flags參數(shù)的中間比特值(第8~15位)來填充掩碼圖像(參考下文)。如果沒有設(shè)置值flags中間比特值,則取默認(rèn)值1。如果填充了掩碼后顯示出來是黑色,不要感到奇怪,因?yàn)樗O(shè)置的值(如果flags的中間值沒有被設(shè)置)為1,所以如果要顯示它,必須需要放大這個(gè)掩碼圖像的數(shù)值。的區(qū)域)。如果mask非空,那么它必須是一個(gè)單通道、8位、像41下面講一下flags參數(shù)。此參數(shù)包含三部分,因?yàn)樗容^復(fù)雜。低8位部分(第0~7位)可以設(shè)為4或8,這個(gè)參數(shù)控制填充算法的連通性。如果設(shè)為4,填充算法只考慮當(dāng)前像素水平方向和垂直方向的相鄰點(diǎn);如果設(shè)為8,除上述相鄰點(diǎn)外,還會(huì)包含對(duì)角線方向的相鄰點(diǎn)。高8位部分(第16~23位)可以設(shè)為CV_FLOODFILL_FIXED_RANGE(如果設(shè)置為這個(gè)值,則只有當(dāng)某個(gè)相鄰點(diǎn)與種子像素之間的差值在指定范圍內(nèi)才填充,否則考慮當(dāng)前點(diǎn)與其相鄰點(diǎn))或者CV_FLOODFILL_MASK_ONLY(如果設(shè)置,函數(shù)不填充原始圖像,而去填充掩碼圖像)。很明顯,如果設(shè)為CV_FLOODFILL_MASK_ONLY,必須輸入符合要求的掩碼。flags的中間比特(第8~15位)的值指定填充掩碼圖像的值。但如果中間比特值為0,則掩碼將用1填充。所有flags可以通過OR操作連接起來。例如,如果想用下面講一下flags參數(shù)。此參數(shù)包含三部分,因?yàn)樗容^復(fù)雜。428鄰域填充,并填充固定像素值范圍,是填充掩碼而不是填充源圖像,以及設(shè)填充值為47,那么輸入的參數(shù)應(yīng)該是:flags=8|CV_FLOODFILL_MASK_ONLY|CV_FLOODFILL_FIXED_RANGE|(47<<8);圖5-20顯示了對(duì)示例圖像的填充操作結(jié)果。圖5-20:漫水填充的效果(上方圖像用灰色填充,下方圖像用白色填充),填充從位于兩個(gè)圖像中心旁的黑色圓形區(qū)域開始;此處指定顏色填充法是在固定范圍內(nèi)進(jìn)行的,loDiff和upDiff的取值都是25.08鄰域填充,并填充固定像素值范圍,是填充掩碼而不是填充源圖像43在這個(gè)填充中使用了CV_FLOODFILL_FIXED_RANGE并選擇了較大的范圍,結(jié)果圖像的大部分區(qū)域被填充(從中心處開始填充)。注意,newVal,loDiff和upDiff都是CvScalar的類型,所以它們可以同時(shí)處理三個(gè)通道(可以通過CV_RGB()宏設(shè)置RGB三色值)。例如令lowDiff=CV_RGB(20,30,40),則三種顏色的lowDiff分別設(shè)為紅色值20,綠色值30,藍(lán)色值40。在這個(gè)填充中使用了CV_FLOODFILL_FIXED_RA44尺寸調(diào)整我們經(jīng)常會(huì)將某種尺寸的圖像轉(zhuǎn)換為其他尺寸的圖像,如放大或者縮小圖像。我們可以用cvResize()函數(shù)來放大或縮小圖像。該函數(shù)可以將源圖像精確轉(zhuǎn)換為目標(biāo)圖像的尺寸。如果源圖像中設(shè)置了ROI,那么cvResize()將會(huì)對(duì)ROI區(qū)域調(diào)整尺寸,以匹配目標(biāo)圖像,同樣,如果目標(biāo)圖像中已設(shè)置ROI的值,那么cvResize()將會(huì)將源圖像進(jìn)行尺寸調(diào)整并填充到目標(biāo)圖像的ROI中。voidcvResize(constCvArr*src,尺寸調(diào)整我們經(jīng)常會(huì)將某種尺寸的圖像轉(zhuǎn)換為其他尺寸的圖像,如放45CvArr*dst,intinterpolation=CV_INTER_LINEAR);最后一個(gè)參數(shù)指定插值方法,默認(rèn)為線性插值法??捎玫牟逯捣椒ㄈ绫?-4所示。表5-4:cvResize()插值方法一般情況下,我們期望源圖像和重采樣后的目標(biāo)圖像之間的映射盡可能地平滑。參數(shù)interpolation控制如何進(jìn)行映射。當(dāng)縮小圖像時(shí),目標(biāo)圖像的像素會(huì)映射為源插值方法含義CV_INTER_NN最近鄰插值CV_INTER_LINEAR線性插值CV_INTER_AREA區(qū)域插值CV_INTER_CUBIC三次樣條插值CvArr*dst,插值方法含義CV_INTER_NN46圖像中的多個(gè)像素,這時(shí)需要進(jìn)行插值。當(dāng)放大圖像時(shí),目標(biāo)圖像上的像素可能無法在源圖像中找到精確對(duì)應(yīng)的像素,也需要進(jìn)行插值。在任何一種情況下,都有z種計(jì)算像素值的方法。其中最簡(jiǎn)單的辦法是將目標(biāo)圖像各點(diǎn)的像素值設(shè)為源圖像中與其距離最近的點(diǎn)的像素值,這就是當(dāng)interpolation設(shè)為CV_INTER_NN時(shí)用的算法?;蛘卟捎镁€性插值算法(CV_INTER_LINEAR),將根據(jù)源圖像附近的4個(gè)(2×2范圍)鄰近像素的線性加權(quán)計(jì)算得出,權(quán)重由這4個(gè)像素到精確目標(biāo)點(diǎn)的距離決定。我們也可以用新的像素點(diǎn)覆蓋原來的像素點(diǎn),然后求取覆蓋區(qū)域的平均值,這種插值算法稱為區(qū)域插值。最后一種選擇是三次樣條插值(CV_INTER_CUBIC)。首先對(duì)源圖像附近的4×4個(gè)鄰近像素進(jìn)行三次樣條擬合,然后將目標(biāo)像素對(duì)應(yīng)的三次樣條值作為目標(biāo)圖像對(duì)應(yīng)像素點(diǎn)的值。圖像中的多個(gè)像素,這時(shí)需要進(jìn)行插值。當(dāng)放大圖像時(shí),目標(biāo)圖像上47圖像金字塔圖像金字塔[Adelson84]被廣泛用于各種視覺應(yīng)用中。圖像金字塔是一個(gè)圖像集合,集合中所有的圖像都源于同一個(gè)原始圖像,而且是通過對(duì)原始圖像連續(xù)降采樣獲得,直到達(dá)到某個(gè)中止條件才停止降采樣。(當(dāng)然,降為一個(gè)像素肯定是中止條件。)有兩種類型的圖像金字塔常常出現(xiàn)在文獻(xiàn)和應(yīng)用中:高斯金字塔[Rosenfeld80]和拉普拉斯[Burt83]金字塔[Adelson84]。高斯金字塔用來向下降采樣圖像,而拉普拉斯金字塔(后面會(huì)簡(jiǎn)單討論)則用來從圖像金字塔圖像金字塔[Adelson84]被廣泛用于各種視覺48金字塔低層圖像中向上采樣重建一個(gè)圖像。要從金字塔第i層生成第i+1層(我們表示第i+1層為Gi+1),我們先要用高斯核對(duì)Gi進(jìn)行卷積,然后刪除所有偶數(shù)行和偶數(shù)列。當(dāng)然,新得到的圖像面積會(huì)變?yōu)樵磮D像的四分之一。按上述過程對(duì)輸入圖像G0循環(huán)執(zhí)行操作就可產(chǎn)生整個(gè)金字塔。OpenCV為我們提供了從金字塔中上一級(jí)圖像生成下一級(jí)圖像的方法:voidcvPyrDown(IplImage*src,IplImage*dst,IplFilterfilter=IPL_GAUSSIAN_5x5);目前,最后一個(gè)參數(shù)filter僅支持CV_GAUSSIAN_5x5(默認(rèn)選項(xiàng))。金字塔低層圖像中向上采樣重建一個(gè)圖像。49同樣,我們可以通過下面相似的函數(shù)(但不是降采樣的逆操作?。F(xiàn)有的圖像在每個(gè)維度上都放大兩倍:voidcvPyrUp(IplImage*src,IplImage*dst,IplFilterfilter=IPL_GAUSSIAN_5x5);在這種情況下,圖像首先在每個(gè)維度上擴(kuò)大為原來的兩倍,新增的行(偶數(shù)行)以0填充。然后給指定的濾波器進(jìn)行卷積(實(shí)際上是一個(gè)在每一維上都擴(kuò)大為兩倍的過濾器)去估計(jì)“丟失”像素的近似值。我們之前注意到函數(shù)PyrUp()并不是函數(shù)PyrDown()的逆操作。之所以這樣是因?yàn)镻yrDown()是一個(gè)會(huì)丟失信息的函數(shù)。為了恢復(fù)原來(更高的分辨率)的圖像,我同樣,我們可以通過下面相似的函數(shù)(但不是降采樣的逆操作?。?0們需要獲得由降采樣操作丟失的信息。這些數(shù)據(jù)形成了拉普拉斯金字塔。下面是拉普拉斯金字塔的第i層的數(shù)學(xué)定義:這里的UP()操作將原始圖像中位置為(x,y)的像素映射到目標(biāo)圖像的(2x+1,2y+1)位置;符號(hào)代表卷積操作,g5×5是5×5高斯核。OpenCV提供的函數(shù)PyrUp()實(shí)現(xiàn)的功能就如Gi-UP(Gi+1)g5x5所定義。因此,我們可以使用OpenCV直接進(jìn)行拉普拉斯運(yùn)算:Li=Gi-PyrUp(Gi+1)高斯金字塔和拉普拉斯金字塔如圖5-21所示,這也顯示了從小圖恢復(fù)原始圖像這個(gè)逆過程。注意:拉普拉斯是就像在前面方程中和圖表中揭示的那樣,它可通過高斯進(jìn)行近似。們需要獲得由降采樣操作丟失的信息。這些數(shù)據(jù)形成了拉普拉斯金字51
有許多操作廣泛使用高斯金字塔和拉普拉斯金字塔,但圖5-21:高斯金字塔及其逆形式——拉普拉斯金字塔圖5-21:高斯金字塔及其逆形式——拉普拉斯金字塔52一個(gè)特別重要的應(yīng)用就是利用金字塔實(shí)現(xiàn)圖像分割(見圖5-22)。圖像分割需要先建立一個(gè)圖像金字塔,然后再Gi的像素和Gi+1的像素直接依照對(duì)應(yīng)關(guān)系,建立起“父-子”關(guān)系。通過這種方式,快速初始分割可以先在金字塔高層的低分辨率圖像上完成,然后逐層對(duì)分割加以優(yōu)化。圖5-22:金字塔分割的閾值threshold1設(shè)置為150,閾值threshold2設(shè)置為30;右邊的圖像只包含左邊圖像的一部分,因?yàn)橛媒鹱炙指顖D像需要將圖像進(jìn)行n次降采樣,其中n是要計(jì)算出的金字塔的層數(shù)(右圖都是從源圖像分割出的512x512大小的區(qū)域)一個(gè)特別重要的應(yīng)用就是利用金字塔實(shí)現(xiàn)圖像分割(見圖5-22)53OpenCV的函數(shù)cvPyrSegmentation()實(shí)現(xiàn)了該算法(可參考B.Jaehne的論文[Jaehne95;Antonisse82]):voidcvPyrSegmentation(IplImage*src,IplImage*dst,CvMemStorage*storage,CvSeq**comp,intlevel,doublethreshold1,doublethreshold2);像以前介紹的一樣,src和dst分別是源圖像和目標(biāo)圖像,它們都必須是8位的,且具有相同的圖像大小和通道的數(shù)量(1或3)。大家可能會(huì)想:“會(huì)產(chǎn)生什么樣的OpenCV的函數(shù)cvPyrSegmentation()實(shí)現(xiàn)54目標(biāo)圖像?”這個(gè)問題并不是沒有道理。目標(biāo)圖像dst可作為執(zhí)行算法時(shí)的所需的臨時(shí)空間,并對(duì)分割結(jié)果可視化。如果觀察此圖像,可以看出每個(gè)分割出的區(qū)域都被涂為單一的顏色(分割區(qū)域中像素的顏色)。由于這個(gè)圖像是執(zhí)行算法時(shí)所需的臨時(shí)計(jì)算空間,所以不能設(shè)為NULL;即使不想要分割結(jié)果,也必須提供一個(gè)圖像。關(guān)于src和dst,需要特別注意一點(diǎn):由于圖像金字塔各層的長(zhǎng)和寬都必須是整數(shù),所以必須要求起始圖像的長(zhǎng)和寬都能夠被2整除,并且能夠被2整除的次數(shù)不少于金字塔總的層數(shù)。例如,對(duì)于4層金字塔的高度或?qū)挾葹?0(2×2×2×5)是滿足要求的,而為90時(shí)(2×3×3×5)就不符合要求了。指針storage用來指向OpenCV的存儲(chǔ)區(qū)。第8章將詳細(xì)討論此內(nèi)容,但現(xiàn)在應(yīng)該知道一點(diǎn),以下命令可以分配目標(biāo)圖像?”這個(gè)問題并不是沒有道理。目標(biāo)圖像dst可作為執(zhí)行55存儲(chǔ)區(qū)域:CvMemStorage*storage=cvCreateMemStorage();comp參數(shù)用于存儲(chǔ)分割結(jié)果更詳細(xì)的信息——存儲(chǔ)區(qū)里一序列相連的組成部分。具體工作機(jī)制將在第8章詳細(xì)講解。但為方便起見,這里簡(jiǎn)要介紹一下cvPyrSegmentation()有關(guān)的知識(shí)。首先要強(qiáng)調(diào)的是,序列(Sequence)是某個(gè)特定類型的結(jié)構(gòu)列表。給定一個(gè)序列,如果已知元素的類型及其在序列中的位置,便可以獲得此序列中元素的個(gè)數(shù)以及這個(gè)元素。訪問序列的方法如例5-1所示。例5-1:對(duì)序列中的每個(gè)元素進(jìn)行操作,此序列的元素是由cvPyrSegmentation()返回的連續(xù)區(qū)域。voidf(IplImage*src,IplImage*dst){ CvMemStorage*storage=cvCreateMemStorage(0); CvSeq*comp=NULL;存儲(chǔ)區(qū)域:56 PyrSegmentation(src,dst,storage,&comp,4,200,50); intn_comp=comp->total; for(inti=0;i<n_comp;i++){ CvConnectedComp*cc=(CvConnectedComp*)cvGetSeqElem(comp,i); do_something_with(cc); } cvReleaseMemStorage(&storage);}此例有以下幾點(diǎn)應(yīng)該注意。首先,觀察存儲(chǔ)的分配情況:cvPyrSegmentation()函數(shù)從中為它要?jiǎng)?chuàng)建的連續(xù)區(qū)域申請(qǐng)內(nèi)存。然后將指針類型設(shè)為CvSeq*,并被初始化為NULL,因?yàn)槠洚?dāng)前值意味著無內(nèi)容。我們將傳遞指向comp的指針給cvPyrSegmentation()函數(shù),這樣comp就可以設(shè)置為cvPyrSegmentation()創(chuàng)建序列的位置。 PyrSegmentation(src,dst,sto57調(diào)用分割操作之后,通過成員變量total,就會(huì)知道序列中的元素個(gè)數(shù)。隨后,我們可以使用通用的cvGetSeqElem()以獲取comp的第i個(gè)元素;然而,由于cvGetSeqElem()是通用的,所以我們必須將返回的指針強(qiáng)制轉(zhuǎn)化為適當(dāng)?shù)念愋停ㄟ@里是CvConnectedComp*類型)。最后,我們需要知道連續(xù)區(qū)域是OpenCV中的基本結(jié)構(gòu)類型之一。可以把它視為描述圖像中“團(tuán)塊”(blob)的一種方法。它具有以下定義:typedefstructCvConnectedComponent{doublearea;CvScalarvalue;CvRectrect;CvSeq*contour;};調(diào)用分割操作之后,通過成員變量total,就會(huì)知道序列中的元58參數(shù)area是區(qū)域的面積。參數(shù)value是區(qū)域顏色的平均值,參數(shù)rect是一個(gè)區(qū)域的外接矩形(定義在父圖像的坐標(biāo)系中)。最后一個(gè)參數(shù)contour是一個(gè)指向另一個(gè)序列的指針。這個(gè)序列可以用來儲(chǔ)存區(qū)域的邊界,通常是點(diǎn)的序列(元素類型為CvPoint)。在cvPyrSegmentation()函數(shù)中,沒有設(shè)參數(shù)contour的值。因此,如果想要區(qū)域中的像素,就只能自己計(jì)算。當(dāng)然得根據(jù)自己的想法來選擇函數(shù)。通常希望獲得一個(gè)二值掩碼圖像,連續(xù)區(qū)域由掩碼中的非0元素指定??梢允褂眠B續(xù)區(qū)域的rect作為掩碼,然后使用cvFloodFill()來選擇矩形內(nèi)所需的像素。參數(shù)area是區(qū)域的面積。參數(shù)value是區(qū)域顏色的平均值,59閾值化完成許多處理步驟之后,通常希望對(duì)圖像中的像素做出最后的決策,或直接剔除一些低于或高于一定值的像素。在OpenCV中,函數(shù)cvThreshold()可以完成這些任務(wù)(見綜述[Sezgin04])。其基本的思想是,給定一個(gè)數(shù)組和一個(gè)閾值,然后根據(jù)數(shù)組中的每個(gè)元素的值是低于還是高于閾值而進(jìn)行一些處理。doublecvThreshold(CvArr*src,CvArr*dst,doublethreshold,doublemax_value,intthreshold_type);閾值化完成許多處理步驟之后,通常希望對(duì)圖像中的像素做出最后的60如表5-5所示,每個(gè)閾值類型對(duì)應(yīng)一個(gè)特定的比較操作,該比較操作在源圖像第i個(gè)像素(srci)和閾值(表中表示為T)之間進(jìn)行。根據(jù)源圖像的像素和閾值之間的關(guān)系,目標(biāo)圖像的像素dsti可能被設(shè)置為0,srci或max_value(表中表示為M)。表5-5:cvThreshold()中閾值類型選項(xiàng)和對(duì)應(yīng)的操作圖5-23有助于我們理解關(guān)于每一個(gè)閾值類型的確切操作。我們來看一個(gè)簡(jiǎn)單的例子。在例5-2中,我們對(duì)圖像中的閾值類型操作CV_THRESH_BINARYdsti=(srci>T)?M:0CV_THRESH_BINARY_INVdsti=(srci>T)?0:MCV_THRESH_TRUNCdsti=(srci>T)?M:srciCV_THRESH_TOZERO_INVdsti=(srci>T)?0:srciCV_THRESH_TOZEROdsti=(srci>T)?srci:0如表5-5所示,每個(gè)閾值類型對(duì)應(yīng)一個(gè)特定的比較操作,該比較操61三個(gè)通道求和,然后在值為100處對(duì)結(jié)果圖像進(jìn)行截?cái)唷@?-2:cvThreshold()函數(shù)的用法圖5-23:在cvThreshold()中不同閾值類型的操作結(jié)果。每個(gè)圖表的水平虛線代表應(yīng)用到最上方圖的閾值,5種閾值類型的操作結(jié)果列于其后三個(gè)通道求和,然后在值為100處對(duì)結(jié)果圖像進(jìn)行截?cái)?。圖5-262voidsum_rgb(IplImage*src,IplImage*dst){ //Allocateindividualimageplanes. IplImage*r=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1); IplImage*g=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1); IplImage*b=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1); //Splitimageontothecolorplanes. cvSplit(src,r,g,b,NULL); //Temporarystorage IplImage*s=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1); //Addequallyweightedrgbvalues. cvAddWeighted(r,1./3.,g,1./3.,0.0,s); cvAddWeighted(s,2./3.,b,1./3.,0.0,s); //Truncatevaluesabove100 cvThreshold(s,dst,150,100,CV_THRESH_TRUNC); cvReleaseImage(&r); cvReleaseImage(&g); cvReleaseImage(&b); cvReleaseImage(&s);}voidsum_rgb(IplImage*src,Ip63intmain(intargc,char**argv){ //Createanamedwindowwiththenameofthefile. cvNamedWindow("Threshold",1); //Loadtheimagefromthegivenfilename. IplImage*src=cvLoadImage("E:\\Pictures\\portrait.png"); IplImage*dst=cvCreateImage(cvGetSize(src),src->depth,1); sum_rgb(src,dst); //Showtheimageinthenamedwindow cvShowImage("Threshold",dst); //Idleuntiltheuserhitsthe"Esc"key. while(1){if((cvWaitKey(10)&0x7f)==27)break;} //Cleanupanddon'tbepiggies cvDestroyWindow("Threshold"); cvReleaseImage(&src); cvReleaseImage(&dst);}《學(xué)習(xí)OpenCV》第5章-圖像處理課件64這里包含幾個(gè)重要的思想。第一,我們通常不會(huì)對(duì)8位數(shù)組進(jìn)行加法運(yùn)算,因?yàn)檩^高的位可能會(huì)溢出。取而代之,我們使用加權(quán)加法算法(cvAddWeighted())對(duì)三個(gè)通道求和;然后對(duì)結(jié)果以100為閾值進(jìn)行截?cái)嗵幚砣缓蠓祷?。cvThreshold()函數(shù)只能處理8位或浮點(diǎn)灰度圖像。圖標(biāo)圖像必須與源圖像的類型一致,或者為8位圖像。事實(shí)上,cvThreshold()還允許源圖像和目標(biāo)圖像是同一圖像。如果我們?cè)诶?-2中使用了臨時(shí)浮點(diǎn)圖像s,例5-3中有等價(jià)的代碼。注意,cvAcc()可以將8位整數(shù)類型圖像累加為浮點(diǎn)圖像;然而,cvADD()卻不能將整數(shù)與浮點(diǎn)數(shù)相加。例5-3:另一種組合不同通道,并閾值化圖像的方法 IplImage*s=cvCreateImage(cvGetSize(src),IPL_DEPTH_32F,1); cvZero(s); cvAcc(b,s); cvAcc(g,s); cvAcc(r,s); cvThreshold(s,s,200,100,CV_THRESH_TRUNC); cvConvertScale(s,dst,1,0);這里包含幾個(gè)重要的思想。第一,我們通常不會(huì)對(duì)8位數(shù)組進(jìn)行加法65自適應(yīng)閾值這是一種改進(jìn)了的閾值技術(shù),其中閾值本身是一個(gè)變量。在OpenCV中,這種方法由函數(shù)cvAdaptiveThreshold()[Jain86]來實(shí)現(xiàn):voidcvAdaptiveThreshold(CvArr*src,CvArr*dst,doublemax_val,intadaptive_method=CV_ADAPTIVE_THRESH_MEAN_C,intthreshold_type=CV_THRESH_BINARY,intblock_size=3,doubleparam1=5);cvAdaptiveThreshold()有兩種不同的自適應(yīng)閾值方法,可自適應(yīng)閾值66以用參數(shù)adaptive_method進(jìn)行設(shè)置。在這兩種情況下,自適應(yīng)閾值T(x,y)在每個(gè)像素點(diǎn)都不同。通過計(jì)算像素點(diǎn)周圍的b×b區(qū)域的加權(quán)平均,然后減去一個(gè)常數(shù)來得到自適應(yīng)閾值,b由參數(shù)block_size指定,常數(shù)由param1指定。如果使用CV_ADAPTIVE_THRESH_MEAN_C方法,那么對(duì)區(qū)域的所有像素平均加權(quán)。如果使用了CV_ADAPTIVE_THRESH_GAUSSIAN_C方法,那么區(qū)域中的(x,y)周圍的像素根據(jù)高斯函數(shù)按照它們離中心點(diǎn)的距離進(jìn)行加權(quán)計(jì)算。最后,參數(shù)threshold_type和表5-5所示的cvThreshold()的參數(shù)threshold_type是一樣的。針對(duì)有很強(qiáng)照明或反射梯度的圖像,需要根據(jù)梯度進(jìn)行閾值化時(shí),自適應(yīng)閾值技術(shù)非常有用。此函數(shù)只能處以用參數(shù)adaptive_method進(jìn)行設(shè)置。在這兩種情況67理單通道8位圖像或浮點(diǎn)圖像,它要求源圖像和目標(biāo)圖像不能使用同一圖像。使用函數(shù)cvAdaptiveThreshold()和cvThreshold()進(jìn)行比較的源代碼在例5-4中。圖5-24顯示了對(duì)有很強(qiáng)的照明梯度圖像的處理結(jié)果。圖的左下部分顯示了使用單一的全局閾值方法cvThreshold()的結(jié)果;圖的右下部分顯示了使用自適應(yīng)局部閾值cvAdaptiveThreshold()的結(jié)果。我們通過自適應(yīng)閾值得到了整個(gè)棋盤格,而在使用單一的閾值時(shí)是不能獲得。請(qǐng)注意例5-4中代碼頂部的使用說明;圖5-24所用的參數(shù)如下:./adaptThresh15117115../Data/cal3-L.bmp例5-4:?jiǎn)我婚撝蹬c自適應(yīng)閾值理單通道8位圖像或浮點(diǎn)圖像,它要求源圖像和目標(biāo)圖像不能使用同68
圖5-24:二值閾值化與自適應(yīng)二值閾值化。輸入圖像(上圖)使用全局閾值時(shí)的二值圖像(左下圖)和使用自適應(yīng)閾值時(shí)的二值圖像(右下圖)[感謝KurtKonolidge提供原始圖像]圖5-24:二值閾值化與自適應(yīng)二值閾值化。輸入圖像(上圖)69//Comparethresholdingwithadaptivethresholding//CALL://./adaptThresholdThresholdlbinaryladaptivemean\//blocksizeoffsetfilenameIplImage*Igray=0,*It=0,*Iat;intmain(intargc,char**argv){ //if(argc!=7){return-1;}//7個(gè)參數(shù)?
//Commandline doublethreshold=100;//(double)atof(argv[1]);//閾值
intthreshold_type=CV_THRESH_BINARY;//atoi(argv[2])?CV_THRESH_BINARY:CV_THRESH_BINARY_INV;//threshold_type閾值類型
intadaptive_method=CV_ADAPTIVE_THRESH_MEAN_C;//atoi(argv[3])?CV_ADAPTIVE_THRESH_MEAN_C:CV_ADAPTIVE_THRESH_GAUSSIAN_C;//自適應(yīng)閾值類型
intblock_size=5;//atoi(argv[4]);//block_size尺寸大小
doubleoffset=2;//(double)atof(argv[5]);//平移 //Readingrayimage if((Igray=cvLoadImage("E:\\測(cè)繪科學(xué)與技術(shù)\\SLAM\\OpenCV\\學(xué)習(xí)OpenCV(中文版)隨書源碼\\LearningOpenCV_Code\\OpenCV_Chessboard.png",CV_LOAD_IMAGE_GRAYSCALE))==0){//argv[6]加載圖像
return-1; }//Comparethresholdingwithad70 //Createthegrayscaleoutputimages It=cvCreateImage(cvSize(Igray->width,Igray->height),IPL_DEPTH_8U,1); Iat=cvCreateImage(cvSize(Igray->width,Igray->height),IPL_DEPTH_8U,1); //Threshold cvThreshold(Igray,It,threshold,255,threshold_type); cvAdaptiveThreshold(Igray,Iat,255,adaptive_method,threshold_type,block_size,offset); //PUTUP2WINDOWS cvNamedWindow("Raw",1); cvNamedWindow("Threshold",1); cvNamedWindow("AdaptiveThreshold",1); //Showtheresults cvShowImage("Raw",Igray); cvShowImage("Threshold",It); cvShowImage("AdaptiveThreshold",Iat); cvWaitKey(0); //Cleanup cvReleaseImage(&Igray); cvReleaseImage(&It); cvReleaseImage(&Iat); cvDestroyWindow("Raw"); cvDestroyWindow("Threshold"); cvDestroyWindow("AdaptiveThreshold"); return(0);} //Createthegrayscaleoutput71第5章圖像處理第5章圖像處理72《學(xué)習(xí)OpenCV》第5章-圖像處理課件73本章各小節(jié)目錄綜述平滑處理圖像形態(tài)學(xué)漫水填充算法尺寸調(diào)整圖像金字塔閾值化練習(xí)本章各小節(jié)目錄綜述74綜述到這里,我們已經(jīng)掌握了關(guān)于圖像處理的所有基礎(chǔ)知識(shí)。我們了解了OpenCV庫(kù)的結(jié)構(gòu),也知道了通常用來表示圖像的基本數(shù)據(jù)結(jié)構(gòu)。通過熟悉HighGUI接口,我們可以運(yùn)行程序并將結(jié)果顯示在屏幕上。掌握了這些用來控制圖像結(jié)構(gòu)的基本方法,我們就可以學(xué)習(xí)更復(fù)雜的圖像處理方法了?,F(xiàn)在,我們來繼續(xù)學(xué)習(xí)高級(jí)的處理方法,即把圖像以“圖像”的方式來處理,而不是由顏色值(或灰度值)組成的數(shù)組。在提到“圖像處理”時(shí),它的意思是:使用圖像結(jié)構(gòu)中所定義的高層處理方法來完成特定任務(wù),這些任務(wù)是圖形和視覺范疇的任務(wù)。綜述到這里,我們已經(jīng)掌握了關(guān)于圖像處理的所有基礎(chǔ)知識(shí)。我們了75平滑處理“平滑處理”也稱“模糊處理”(blurring),是一項(xiàng)簡(jiǎn)單且使用頻率很高的圖像處理方法。平滑處理的用途有很多,但最常見的是用來減少圖像上的噪聲或者失真。降低圖像分辨率時(shí),平滑處理是很重要的(在本章的“圖像金字塔”部分會(huì)詳細(xì)介紹這一點(diǎn))。目前OpenCV可以提供五種不同的平滑操作方法,所有操作都由cvSmooth函數(shù)實(shí)現(xiàn),該函數(shù)可以將用戶所期望的平滑方式作為參數(shù)。平滑處理“平滑處理”也稱“模糊處理”(blurring),是76voidcvSmooth(constCvArr*src,CvArr*dst,intsmoothtype=CV_GAUSSIAN,intparam1=3,intparam2=0,doubleparam3=0,doubleparam4=0);src和dst分別是平滑操作的輸入圖像和結(jié)果,cvSmooth()函數(shù)包含4個(gè)參數(shù),param1,param2,param3和param4。這些參數(shù)的含義取決于smoothtype的值,這些值可能是表5.1中列出的任何一個(gè)。(請(qǐng)注意,有些操作不支持inplace方式的輸入。inplace方式意味著輸voidcvSmooth(77入圖像與結(jié)果圖像是同一個(gè)圖像。)表5-1:平滑操作的各種類型平滑類型名稱支持No輸入類型輸出類型簡(jiǎn)要介紹CV_BLUR簡(jiǎn)單模糊是1,38u,32f8u,32f對(duì)每個(gè)像素param1×param2鄰域求和,并做縮放1/(param1param2)CV_BLUR_NO_SCALE簡(jiǎn)單無縮放變換的模糊否18u16s(占8u的資源)或32f(占32f的資源大小)對(duì)每個(gè)像素的param1×param2鄰域求和CV_MEDIAN中值模糊否1,38u8u對(duì)圖像進(jìn)行核大小為parma1×param2的中值濾波CV_GAUSSIAN高斯模糊是1,38u,32f8u(占8u的資源)或32f(占32f的資源)對(duì)圖像進(jìn)行核大小為param1×param2的高斯卷積CV_BILATERAL雙邊濾波否1,38u8u應(yīng)用雙線性3×3濾波,顏色sigma=param1,空間sigma=param2入圖像與結(jié)果圖像是同一個(gè)圖像。)平滑類型名稱支持No輸入類型78圖5.1CV_BLUR所例舉的simpleblur是最簡(jiǎn)單的一項(xiàng)操作。輸出圖像的每一個(gè)像素是窗口中輸入圖像對(duì)應(yīng)像素的簡(jiǎn)單平均值。simpleblur支持1~4個(gè)圖像通道,可以處理8位圖像或者32位的浮點(diǎn)圖像。圖5-1:簡(jiǎn)單圖像平滑處理:左邊為輸入圖像,右邊為結(jié)果圖像圖5.1CV_BLUR所例舉的simpleblur是最簡(jiǎn)單79不是所有的模糊操作的輸入和結(jié)果圖像類型都相同,CV_BLUR_NO_SCALE(不縮放比例而進(jìn)行模糊處理)與simpleblur本質(zhì)上是相同的,但并沒有計(jì)算其平均值的操作。因此,輸入圖像和結(jié)果圖像必須有不同的數(shù)值精度,才能保證模糊操作不會(huì)導(dǎo)致錯(cuò)誤溢出。不縮放比例的simpleblur支持8位的輸入圖像,結(jié)果圖像的數(shù)據(jù)類型必須是IPL_DEPTH_16S(CV_16S)或IPL_DEPTH_32S(CV_32S)。同樣的操作也可以在32位浮點(diǎn)圖像上進(jìn)行,結(jié)果圖像也應(yīng)該是32位浮點(diǎn)類型。簡(jiǎn)單無縮放變換的模糊不支持inplace方式:輸入圖像與結(jié)果圖像必須不同。(在8位和16位情況下,很明顯不能用inplace方式;用32位圖像時(shí),也保持這一規(guī)定。)用戶選擇不縮放比例的模糊操作是因?yàn)槠浔瓤s放比例的模糊操作要快一些。不是所有的模糊操作的輸入和結(jié)果圖像類型都相同,CV_BLUR80中值濾波器(CV_MEDIAN)[Bardyn84]將中心要素的正方形鄰域內(nèi)的每個(gè)像素值用中間像素值(不是平均像素值)替換,它可以用來處理單個(gè)通道、三個(gè)通道或者四個(gè)通道8位的圖像,但不可以inplace操作。中值濾波的結(jié)果見圖5-2?;谄骄惴ǖ膕impleblur對(duì)噪聲圖像特別是有大的孤立點(diǎn)(有時(shí)被稱為“鏡頭噪聲”)的圖像非常敏感,即使有極少數(shù)量點(diǎn)存在較大差異也會(huì)導(dǎo)致平均值的明顯波動(dòng),因此中值濾波可以通過選擇中間值避免這些點(diǎn)的影響。中值濾波器(CV_MEDIAN)[Bardyn84]將中心要81下一個(gè)平滑濾波器是Gaussianfilter(CV_GAUSSIAN),雖然它不是最快的,但它是最有用的濾波器。高斯濾波用卷積核與輸入圖像的每個(gè)點(diǎn)進(jìn)行卷積,最終計(jì)算結(jié)果之和作為輸出圖像的像素值。對(duì)于高斯模糊(圖5-3),前兩個(gè)參數(shù)代表濾波器窗口的寬度和高度,可選擇的第三個(gè)參數(shù)代表卷積核的sigma值(是最大寬度的四分之一)。如果第?個(gè)參數(shù)未指定,系統(tǒng)將會(huì)根據(jù)窗口尺寸通過下面的方程來自動(dòng)確定高斯核的各個(gè)參數(shù)。圖5-3:對(duì)一維像素?cái)?shù)組進(jìn)行高斯模糊參數(shù)1:濾波器寬度參數(shù)2:濾波器高度下一個(gè)平滑濾波器是Gaussianfilter(CV_GA82如果用戶希望高斯核不對(duì)稱,那么可以引入第四個(gè)參數(shù)。這樣,第三個(gè)和第四個(gè)參數(shù)分別為水平方向和垂直方向的sigma值。如果第三個(gè)和第四個(gè)參數(shù)已經(jīng)給出,但是前兩個(gè)參數(shù)被設(shè)為0,那么窗口的尺寸會(huì)根據(jù)sigma值自動(dòng)確定。高斯濾波的OpenCV的實(shí)現(xiàn)還為幾個(gè)常見的核提供了更高的性能優(yōu)化。具有標(biāo)準(zhǔn)sigma值的3×3,5×5和7×7比其他核具有更優(yōu)的性能。高斯模糊支持單個(gè)通道或者三個(gè)通道的8位或32位的浮點(diǎn)格式圖像,可以進(jìn)行inplace方式操作。高斯模糊的效果見圖5-4。如果用戶希望高斯核不對(duì)稱,那么可以引入第四個(gè)參數(shù)。這樣,第三83OpenCV支持的第五個(gè)也是最后一個(gè)平滑操作被稱作雙邊濾波(bilateralfiltering)[Tomasi98],舉例見圖5-5。雙邊濾波是“邊緣保留濾波”的圖像分析方法中的一種。將它與高斯平滑對(duì)比后會(huì)更容易理解。進(jìn)行高斯濾波的????是真實(shí)在空間內(nèi)的像素是緩慢變化的,因此臨近點(diǎn)的像素變化不會(huì)太明顯。但是隨機(jī)??個(gè)點(diǎn)就可能形成很大的像素差(也就是說空間噪聲點(diǎn)不是相互聯(lián)系的)。正是??這一點(diǎn),高斯濾波在保留信號(hào)的條件下減少噪聲。遺憾的是,這種方法在接近??處就無效了,在那兒你不希望像素與相鄰像素相關(guān)。因此,高斯濾波會(huì)磨平邊??。而雙邊濾波能夠提供一種不會(huì)將邊緣的平滑掉的方法,但作為代價(jià),需要更多??時(shí)間。與高斯濾波類似,雙邊濾波會(huì)依據(jù)每個(gè)像素及其鄰域OpenCV支持的第五個(gè)也是最后一個(gè)平滑操作被稱作雙邊濾波(84構(gòu)造一個(gè)加權(quán)平均值,加權(quán)計(jì)算包括兩個(gè)部分,其中第一部分加權(quán)方式與高斯平滑中的相同,第二部分也屬于高斯加權(quán),但不是基于中心像素點(diǎn)與其他像素點(diǎn)的空間距離之上的加權(quán),而是基于其他像素與中心像素的亮度差值的加權(quán)??梢詫㈦p邊濾波視為高斯平滑,對(duì)相似的像素賦予較高的權(quán)重,不相似的像素賦予較小的權(quán)重。這種濾波的典型??就是使處理過的圖像看上去像是一幅源圖的水彩畫,可用于圖像的分割。雙邊濾波含有兩個(gè)參數(shù)。第一個(gè)參數(shù)代表空域中使用的高斯核的寬度,和高斯濾波的sigma參數(shù)類似。第二個(gè)參數(shù)代表顏色域內(nèi)高斯核的寬度。第二個(gè)參數(shù)越大,表明待濾波的強(qiáng)度(或顏色)范圍越大(因此不連續(xù)的程度越高,以便保留)。構(gòu)造一個(gè)加權(quán)平均值,加權(quán)計(jì)算包括兩個(gè)部分,其中第一部分加權(quán)方85圖像形態(tài)學(xué)OpenCV為進(jìn)行圖像的形態(tài)學(xué)變換[Serra83]提供了快速、方便的函數(shù)?;镜男螒B(tài)轉(zhuǎn)換是膨脹與腐蝕,它們能實(shí)現(xiàn)多種功能:例如消除噪聲、分割出獨(dú)立的圖像元素以及在圖像中連接相鄰的元素。形態(tài)學(xué)也常被用于尋找圖像中的明顯的極大值區(qū)域或極小值區(qū)域以及求出圖像的梯度。圖像形態(tài)學(xué)OpenCV為進(jìn)行圖像的形態(tài)學(xué)變換[Serra8386膨脹和腐蝕膨脹是指將一些圖像(或圖像中的一部分區(qū)域,稱之為A)與核(稱之為B)進(jìn)行卷積。核可以是任何的形狀或大小,它擁有一個(gè)單獨(dú)定義出來的參考點(diǎn)(anchorpoint)。多數(shù)情況下,核是一個(gè)小的中間帶有參考點(diǎn)的實(shí)心正方形或圓盤。核可以視為模板或掩碼,膨脹是求局部最大值的操作。核B與圖像卷積,即計(jì)算核B覆蓋的區(qū)域的像素點(diǎn)最大值,并把這個(gè)最大值賦值給參考點(diǎn)指定的像素。這樣就會(huì)使圖像中的高亮區(qū)域逐漸增長(zhǎng),如圖5-6所示。這樣的增長(zhǎng)就是“膨脹操作”的初衷。圖5-6:形態(tài)學(xué)膨脹:在核B下取最大像素值膨脹和腐蝕圖5-6:形態(tài)學(xué)膨脹:在核B下取最大像素值87腐蝕是膨脹的反操作。腐蝕操作要計(jì)算核區(qū)域像素的最小值。腐蝕可以通過下面的算法生成一個(gè)新的圖像:當(dāng)核B與圖像卷積時(shí),計(jì)算被B覆蓋區(qū)域的最小像素值,并把這個(gè)值放到參考點(diǎn)上。腐蝕后的圖像如圖5-7所示。一般來說,膨脹擴(kuò)展了區(qū)域A,而腐蝕縮小了區(qū)域A。此圖5-7
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 美容美發(fā)店員工入股2025年度全新合作框架合同匯編
- 2025年度高端服裝店品牌代理權(quán)轉(zhuǎn)讓合同范本
- 砌體抹灰勞務(wù)分包合同書
- 工業(yè)生產(chǎn)過程質(zhì)量控制要點(diǎn)
- 農(nóng)業(yè)養(yǎng)殖業(yè)智能化養(yǎng)殖管理系統(tǒng)建設(shè)
- 新能源車充電樁建設(shè)合同
- 汽車工程車輛維護(hù)與故障診斷技能考試試題集
- 中學(xué)生物多樣性的感悟
- 城市商業(yè)管理系統(tǒng)升級(jí)服務(wù)協(xié)議
- 給排水安裝工程勞務(wù)合同
- 教科版科學(xué)五年級(jí)下冊(cè)《熱》單元教材解讀分析
- 安脈學(xué)生信息化管理系統(tǒng)(課堂PPT)
- 中小學(xué)基本辦學(xué)條件標(biāo)準(zhǔn)(建設(shè)用地校舍建設(shè)標(biāo)準(zhǔn))
- 化學(xué)實(shí)驗(yàn)室安全培訓(xùn)課件課件
- 渤海灣盆地構(gòu)造演化及其油氣意義
- word公章模板
- 中西醫(yī)結(jié)合腫瘤學(xué)試卷(含答案)
- 開學(xué)第一課我們開學(xué)啦主題班會(huì)PPT課件(帶內(nèi)容)
- 體育訓(xùn)練隊(duì)隊(duì)規(guī)
- 電梯工程開工報(bào)告(直梯)(共1頁)
- ANSI B165《鋼制管法蘭及法蘭管件》
評(píng)論
0/150
提交評(píng)論