點擊上方AI人工智慧初學者,訂閱我!此刻開始我們一起學習進步!
1、訪問圖像的各個像素強度
2、OpenCV中直方圖的計算和均衡
3、圖像的幾何變換
3.1、圖像大小調整
3.2、圖像平移與旋轉
4、對圖像進行濾波操作
4.1、均值濾波
4.2、高斯濾波
4.2、中值濾波
當我們處理圖像時,有時會需要訪問特定位置的像素強度值,當我們想要改變一組像素的亮度或對比度或者想執行一些其他像素級操作時,這就非常有用。對於8位灰度圖像來說,一個點的強度值在0到255範圍內;而對於具有藍色、綠色和紅色三個通道的彩色圖像,每個點都具有三組不同的強度值,每一組的值都在0到255之間。
OpenCV提供一個cv::Mat::at<>方法,可以訪問各個通道圖像裡特定位置的強度值。它需要一個參數,就是要訪問強度值的點位置,這裡使用帶有行列值作為參數的Point類來傳遞該點位置。對於灰度圖像,這個方法將返回一個標量對象;對於彩色圖像,它將返回三個強度值的矢量。用於訪問灰度及彩色圖像中特定位置以獲得該像素強度的代碼如下:
首先讀取灰度圖像,然後在該圖像對象上調用at方法,測量點(100,50)的強度值,表示第100行和第50列處的像素,然後得到一個返回的標量,存儲在強度變量中,將這個值顯示在控制臺上。彩色圖像遵循相同的程序,但返回值是三個強度的矢量,存儲在Vec3b對象中,強度值顯示在控制臺上。上述程序的輸出:
直方圖是圖像的一個非常重要的屬性,因為它提供該圖像外觀的全局描述。可以從直方圖獲得大量信息,包括表示圖像中灰度級出現的相對頻率,基本上由是X軸上的灰度級與Y軸上每個灰度級的像素數量所組成。如果直方圖集中在左側,則圖像將非常暗;如果它集中在右側,則圖像將非常亮。通常應該是均勻分布,能得到較好視覺效果。
完美圖像在其所有灰度級中具有等量的像素,因此在整個範圍內直方圖應在較大的動態範圍裡有相同數量的像素,這可以通過直方圖均衡的技術來實現,這是所有計算機視覺應用中非常重要的預處理步驟。
以下代碼描述灰度圖像上直方圖均衡的過程:
將讀取的圖像上載到設備顯存裡,準備進行直方圖均衡。由於這是個計算密集的步驟,因此CUDA加速將有助於提高程序的性能。OpenCV為直方圖均衡提供equalizeHist函數,需要兩個參數:第一個參數是源圖像,第二個參數是目標圖像。然後將目標圖像下載回主機,並顯示在控制臺上。直方圖均衡後的輸出如圖
可以看出,經過直方圖均衡的圖像比原始圖像的視覺質量更好。
直方圖均衡也可以在彩色圖像上完成,而且必須在個別通道上進行,因此彩色圖像必須分成三個通道,每個通道各自執行直方圖均衡,然後合併通道再重建圖像。以下代碼描述彩色圖像上直方圖均衡的過程:
BGR顏色空間的直方圖通常不太均衡,HSV和YCrCb顏色空間可以輔助處理,因此代碼中先將BGR顏色空間轉為HSV顏色空間,然後使用split函數將其拆分為三個獨立的通道。如此一來,色調和飽和度通道包含顏色信息,這兩個通道沒有需要均衡的地方,直方圖只要針對值通道進行均衡就行,然後再使用merge函數將三個通道合併,重建彩色圖像。最後將HSV彩色圖像轉換回BGR顏色空間,用imshow顯示出來。本段代碼執行的輸出如圖:
總的來說,直方圖均衡能提高圖像的視覺質量,因此對於所有計算機視覺應用來說都是非常重要的預處理步驟。
計算機視覺應用中,調整圖像大小、平移和旋轉圖像都是經常需要的功能。
3.1、圖像大小調整
在某些計算機視覺應用中,圖像需要符合指定尺寸,因此需要將任意大小的圖像轉換成指定尺寸。OpenCV提供調整圖像大小的功能。圖像大小調整的代碼如下:
如代碼所示,這裡有兩個不同函數可以獲取圖像的高度和寬度:Mat對象的rows和cols屬性分別描述圖像的height和width;Mat對象也可以用查找圖像大小的size()方式來獲取height和width屬性。圖像以兩種方式調整大小:在第一種方式中,圖像大小調整為(200,200)這個特定尺寸;第二種方式,調整為原始尺寸的一半。OpenCV為此操作提供resize函數,需要四個參數。
前兩個參數分別是源圖像和目標圖像,第三個參數是目標圖像的大小,是使用Size對象定義的。調整圖像大小時,必須在源圖像中插入像素值以生成目標圖像,這裡有多種插值方法,諸如雙線性插值、雙三次插值、區域插值等都可用來作為像素的插值。這些插值方法作為resize函數的第四個參數,可以是cv::INTER_LINEAR(雙線性)、cv::INTER_CUBIC(雙三次)或cv::INTER_AREA(區域)。圖像大小調整代碼的輸出如圖:
注意:不同的插值方法也會帶來速度的衰減,三線性插值相對比較慢的。
3.2、圖像平移與旋轉
圖像平移與旋轉在一些計算機視覺應用中是重要的幾何變換,OpenCV提供一個簡單的API來對圖像執行這些變換。執行平移與旋轉的代碼如下:
在代碼中,使用Mat對象創建此矩陣,其中70作為x方向的偏移量、50作為y方向的偏移量。此矩陣作為參數傳遞給warpAffine函數以進行圖像平移,warpAffine函數的其他參數分別是源圖像、目標圖像和輸出圖像的大小。
旋轉過程則需要創建一個旋轉矩陣,以特定點為中心,對圖像執行特定角度的圖像旋轉。OpenCV提供cv::getRotationMatrix2D函數來構造這個旋轉矩陣,這個函數需要三個參數:第一個參數是旋轉點,也就是圖像旋轉中心;第二個參數是以度為單位的旋轉角度,本範例指定為45度;最後一個參數是尺度(scale),本範例指定為1。然後將構造的旋轉矩陣作為參數傳遞給warpAffine函數,以進行圖像旋轉。
圖像平移和圖像旋轉程序的輸出:
前面所描述的各種方法都只針對單像素強度進行處理,因此也稱為「點處理」方法。而更多時候,查看像素的鄰域關係比只處理單像素強度有更大的用途,我們稱之為「鄰域處理」技術。鄰域可以是3×3,5×5,7×7等以特定像素為中心的矩陣。圖像濾波是一種重要的鄰域處理技術。
濾波是信號處理中的一個重要概念:拒絕或允許某特定頻段通過。如何在圖像中測量頻率?如果某區域內的灰度級變化緩慢,那麼就是低頻區域;如果灰度級變化劇烈,這就是高頻區域。通常,圖像的背景被視為是低頻區域,邊緣是高頻區域。
4.1、均值濾波
平均濾波器對鄰域像素執行平均操作。如果圖像中存在高斯噪聲,則可以使用這種低通平均濾波器來消除噪聲,但平均操作會使圖像邊緣變得模糊。鄰域可以是3×3,5×5,7×7,依此類推。濾波器窗口的尺寸越大,圖像的模糊程度就越大。
cv::Ptr是智能指針的模板類,用於存儲cv::cuda::Filter類型的濾波器。接著用create-BoxFilter函數來創建不同窗口大小的平均濾波器,這個函數需要三個強制參數和三個可選參數:第一個和第二個參數是源圖像和目標圖像的數據類型,這裡設定為8位無符號灰度的CV_8UC1圖像;第三個參數定義濾波器窗口的大小,可以是3×3、5×5、7×7等;第四個參數是表示位於內核中心點的錨點,默認值為(-1,-1)。最後還有兩個關於像素插值方法和邊界值的可選參數,這裡省略。
創建出來的濾波器指針有一個apply方法,能將創建的濾波器用在所有圖像上,它需要三個參數:第一個參數是源圖像,第二個參數是目標圖像,第三個可選參數是CUDA流,用於本書前面所述的多任務處理。代碼中,在圖像上應用了三個不同大小的平均濾波器,執行結果如圖6-8所示。往下一次kernel增大:
從輸出的結果可以看出,雖然大型濾波器可以消除更多噪聲,但是隨著濾波器尺寸的增加,更多的像素被平均處理,導致圖像變得更加模糊。
4.2、高斯濾波
高斯濾波器使用具有高斯分布的掩碼來過濾圖像,而不是簡單的平均掩碼。這個濾波器還在圖像上引入平滑模糊,這個方法已經被廣泛用於消除圖像中的噪聲。
createGaussianFilter函數用於為高斯濾波器創建掩碼,需要提供源圖像/目標圖像的數據類型、濾波器的大小以及水平方向標準差作為這個函數的參數。我們還可以提供豎直方向標準差作為參數,如果不提供的話,會用水平方向標準差作為其默認值,然後用apply方法創建出不同大小的高斯掩碼應用於圖像處理。本段代碼的輸出如圖:
同樣地,隨著高斯濾波器尺寸的增加,圖像變得更加模糊。高斯濾波器用於消除噪聲並在圖像上引入平滑模糊。
4.3、中值濾波
當圖像受到椒鹽噪聲的影響,那麼平均濾波器或高斯濾波器是消除不了的,這時候需要一個非線性的濾波器。用鄰域的中值運算去替代平均值的方式可以幫助消除椒鹽噪聲。在這個濾波器中,鄰域中的9像素值的中值放置於中心像素處,這將能消除椒鹽噪音所產生的過高或過低的極端值。雖然OpenCV和CUDA提供了中值濾波功能,但它比OpenCV的常規函數慢。
OpenCV中的medianBlur函數用於實現中值濾波器,它需要三個參數:第一個參數是源圖像,第二個參數是目標圖像,第三個參數是中值運算的窗口大小。中值濾波的輸出如圖:
如圖所示,源圖像受椒鹽噪聲的影響。通過3×3尺寸的中值濾波器完全消除了這種噪聲,而且沒有產生極端模糊。因此,當圖像應用受椒鹽噪聲影響時,中值濾波是一個非常重要的預處理步驟。
筆記大部分內容來源於書籍:【基於GPU加速的計算機視覺編程】
關注【AI人工智慧初學者】並回復【cuda9】即可獲取本文的完整源碼,只希望可以幫到你,當然,大佬除外啦~~~~
聲明:轉載請說明出處
下方為小生公眾號,還望包容接納和關注,非常期待與您的美好相遇,讓我們以夢為馬,砥礪前行。
長按識別二維碼關注一下
更多精彩內容可回復關鍵詞
每篇文章的主題即可
點「在看」給我一朵小黃花