【OpenCV:從零到一】12:圖像金字塔(上採樣、降採樣)

前言
這是我《OpenCV:從零到一》專欄的第十二篇博客,想看跟多請戳
本文概要
上採樣(cv::pyrUp) – zoom in 放大
降採樣 (cv::pyrDown) – zoom out 縮小
subtract
歸一化 normalize
案例代碼
大概內容:上採樣、降採樣、歸一化 。

#include <opencv2/opencv.hpp>
#include <iostream>
#include "math.h"

using namespace cv;
int main(int agrc, char** argv) {
	Mat src, dst;
	src = imread("D:\\86186\\Documents\\opencv\\lena.jpg");
	if (!src.data) {
		printf("could not load image...");
		return -1;
	}

	char INPUT_WIN[] = "input image";
	char OUTPUT_WIN[] = "sample up";
	namedWindow(INPUT_WIN, WINDOW_AUTOSIZE);
	namedWindow(OUTPUT_WIN, WINDOW_AUTOSIZE);
	imshow(INPUT_WIN, src);

	// 上採樣
	pyrUp(src, dst, Size(src.cols * 2, src.rows * 2));
	imshow(OUTPUT_WIN, dst);

	// 降採樣
	Mat s_down;
	pyrDown(src, s_down, Size(src.cols / 2, src.rows / 2));
	imshow("sample down", s_down);

	// DOG
	Mat gray_src, g1, g2, dogImg;
	cvtColor(src, gray_src, COLOR_BGR2GRAY);
	GaussianBlur(gray_src, g1, Size(5, 5), 0, 0);
	GaussianBlur(g1, g2, Size(5, 5), 0, 0);
	subtract(g1, g2, dogImg, Mat());

	// 歸一化顯示
	normalize(dogImg, dogImg, 255, 0, NORM_MINMAX);
	imshow("DOG Image", dogImg);

	waitKey(0);
	return 0;
}

運行效果:
在這裏插入圖片描述

解析及注意事項

  • 我們在圖像處理中常常會調整圖像大小,最常見的就是放大(zoom in)和縮小(zoom out),儘管幾何變換也可以實現圖像放大和縮小,但是這裏我們介紹圖像金字塔
  • 一個圖像金字塔式一系列的圖像組成,最底下一張是圖像尺寸最大,最上方的圖像尺寸最小,從空間上從上向下看就想一個古代的金字塔。
  • pyrUp(Mat src, Mat dst) 生成的圖像是原圖在寬與高各放大兩倍
  • pyrDown(Mat src, Mat dst)生成的圖像是原圖在寬與高各縮小1/2
  • 之前有介紹過multiply,現在又有一個subtract,兩個都是四則運算,很相像,但是這個函數對於不同圖片處理的方式不同,具體如下
    在這裏插入圖片描述
  • 歸一化顯示圖片可以用normalize(事實上不僅僅可以用來歸一化)其中要注意一點的是Saturation is not applied when the output array has the depth CV_32S. You may even get result of an incorrect sign in the case of overflow. 深度爲CV_32S的圖片不調用saturate函數,溢出會得到錯誤的結果。標準化類型有如下幾種(不止)
    在這裏插入圖片描述

全註釋代碼

#include <opencv2/opencv.hpp>
#include <iostream>
#include "math.h"

using namespace cv;
int main(int agrc, char** argv) {
	Mat src, dst;
	src = imread("D:\\86186\\Documents\\opencv\\lena.jpg");
	if (!src.data) {
		printf("could not load image...");
		return -1;
	}

	char INPUT_WIN[] = "input image";
	char OUTPUT_WIN[] = "sample up";
	namedWindow(INPUT_WIN, WINDOW_AUTOSIZE);
	namedWindow(OUTPUT_WIN, WINDOW_AUTOSIZE);
	imshow(INPUT_WIN, src);

	// 上採樣
	pyrUp(src, dst, Size(src.cols * 2 , src.rows * 2));
	//pyrUp(src, dst, dst的大小,boderType);Size大小限制如下
	//|dstsize.width−src.cols∗2 | ≤(dstsize.width mod 2) 和 |dstsize.height−src.rows∗2 |≤(dstsize.height mod 2)
	imshow(OUTPUT_WIN, dst);

	// 降採樣
	Mat s_down;
	pyrDown(src, s_down, Size(src.cols / 2 + 1, src.rows / 2));
	//和pyrUp一模一樣,Size的大小一定要滿足|dstsize.width∗2−src.cols|≤2 和  |dstsize.height∗2−src.rows|≤2
	//也就是說Size大小隻能在兩倍左右,否則會報錯。寬和高不一定要一樣
	//這兩個函數的Size的參數都有默認值,也就是我們上面填的值
	imshow("sample down", s_down);

	
	Mat gray_src, g1, g2, dogImg;
	cvtColor(src, gray_src, COLOR_BGR2GRAY);
	GaussianBlur(gray_src, g1, Size(5, 5), 0, 0);//高斯模糊(原圖,目標,核大小,sigemaX,sigemaY)
	GaussianBlur(g1, g2, Size(5, 5), 0, 0);
	subtract(g1, g2, dogImg, Mat());//Calculates the per-element difference between two arrays or array and a scalar.
	/*運算關係有些複雜,但是大體上是src1-src2
		InputArray 	src1,
		InputArray 	src2,
		OutputArray 	dst,
		InputArray 	mask = noArray(),//可選操作掩碼; 這是一個8位單通道數組,用於指定要更改的輸出數組的元素。
		int 	dtype = -1  //輸出圖像的深度,-1爲默認
	Saturation is not applied when the output array has the depth CV_32S. You may even get result of an incorrect sign in the case of overflow.
	深度爲CV_32S的圖片不調用saturate函數,溢出會得到錯誤的結果。
	*/
	normalize(dogImg, dogImg, 255, 0, NORM_MINMAX);// 歸一化顯示
	/*
	InputArray 	src,
	InputOutputArray 	dst,
	double 	alpha = 1,//下界
	double 	beta = 0,//上界
	int 	norm_type = NORM_L2,
	int 	dtype = -1,
	InputArray 	mask = noArray() 
	*/
	imshow("dstImage", dogImg);

	waitKey(0);
	return 0;
}

翻譯筆記
sample n.樣品;
norm 標準;規範

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章