OpenCV 實現最小值降取樣
阿新 • • 發佈:2018-12-11
在處理某些高分辨的影象時,如果直接對其原圖進行操作處理,那麼效率是很低下的,因此我們要在儘可能的保留影象資訊的情況下,減小影象的解析度大小,此時就需要用到影象的降取樣。由於我本人之前都是在處理裂縫的影象,而裂縫一般都是屬於灰度值較低的部分,因此本文采用最小值的將取樣法,將裂縫資訊得以完整的保留,以便後續進行分析計算。具體操作如下:
實際上如果結合OpenCV實現我們上述的功能還是挺簡單的,下面我分別給出Python和c++的程式碼:
Python程式碼如下:
""" 最小值取樣法Python實現 _author_ZhouJH_""" import numpy as np import cv2 im = cv2.imread('c:\\users\\xa\\desktop\\test.jpg',0)#讀入一張灰度圖 a, b = im.shape[:2] m = int(a / 5) # hight #降取樣後圖像的長和寬,如果不能被整除理論上應該是加上邊框的 n = int(b / 5) # length 降取樣為原來的1/5 """ 降取樣函式,為了簡單粗暴先採用列表儲存降取樣後的值,然後reshape """ def Downsampling(m,n): img = [] for x in range(m): for y in range(n): s = im[5 * x:5 * (x + 1), 5 * y:5 * (y + 1)].min() #選取視窗中灰度值最小的那個值,作為降取樣後的值 img.append(s) down_img = np.array((img), np.uint8).reshape(m, n) # 將取樣後的影象 return down_img if __name__=='__main__': p=Downsampling(m,n) cv2.imshow('1',p) cv2.waitKey(0) cv2.destroyAllWindows()
下面這張為降取樣後的裂縫影象,可以看出,影象整體變暗,但是裂縫的細節被完整的儲存下來。
c++程式碼如下:
/*最小值取樣c++實現 author_ZhouJH */ #include<iostream> #include<opencv2/opencv.hpp> #include <vector> using namespace std; using namespace cv; /* 對影象進行降取樣 */ void Downsampling(const Mat &mat) { int a = mat.rows / 5; int b = mat.cols / 5;//降取樣後的行數和列數 double minv = 0, maxv = 0; double* minp = &minv; double* maxp = &maxv; Mat m = Mat(a, b, CV_8UC1, Scalar::all(0)); //初始化 //Mat m = mat(Rect(0, 0, b,a));//初始化 for (int i = 0; i < (a); i++) { for (int j = 0; j < (b); j++) { Mat im = mat(Rect(5*j, 5*i, 5, 5));//選取影象區域性,實現5*5的滑動視窗 minMaxIdx(im, minp, maxp); //找出該區域的灰度最小值 m.at<uchar>(i, j) = (*minp);//重新將其寫入矩陣中 } } imshow("1", m); waitKey(0); } int main() { Mat img, gray; img = imread("c:\\users\\xa\\desktop\\test.jpg"); cvtColor(img, gray, COLOR_RGB2GRAY);//轉為灰度圖 Downsampling(gray); }
效果和上面是一樣的,如下所示:
基於最小值的降取樣方法實現起來還是比較簡單的,但是卻很有用的,一般可作為影象的預處理部分。程式是之前專案的一個小部分,故特此總結和大家分享!