1. 程式人生 > >OpenCV 實現最小值降取樣

OpenCV 實現最小值降取樣

在處理某些高分辨的影象時,如果直接對其原圖進行操作處理,那麼效率是很低下的,因此我們要在儘可能的保留影象資訊的情況下,減小影象的解析度大小,此時就需要用到影象的降取樣。由於我本人之前都是在處理裂縫的影象,而裂縫一般都是屬於灰度值較低的部分,因此本文采用最小值的將取樣法,將裂縫資訊得以完整的保留,以便後續進行分析計算。具體操作如下:

實際上如果結合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);
}

效果和上面是一樣的,如下所示:

基於最小值的降取樣方法實現起來還是比較簡單的,但是卻很有用的,一般可作為影象的預處理部分。程式是之前專案的一個小部分,故特此總結和大家分享!