OpenCV 實戰 - 圖像融合(cv::copyTo())

cv::copyTo()

OpenCV 中 cv::copyTo 是用來複制矩陣對象 Mat 的,可以實現直接創建一個副本,且在副本矩陣上的操作不會影響原矩陣。

cv::copyTo() 聲明

 /** @brief Copies the matrix to another one.

The method copies the matrix data to another matrix. Before copying the data, the method invokes :
@code
    m.create(this->size(), this->type());
@endcode
so that the destination matrix is reallocated if needed. While m.copyTo(m); works flawlessly, the function does not handle the case of a partial overlap between the source and the destination matrices.

When the operation mask is specified, if the Mat::create call shown above reallocates the matrix, the newly allocated matrix is initialized with all zeros before copying the data.
@param m Destination matrix. If it does not have a proper size or type before the operation, it is reallocated.
 */
void copyTo( OutputArray m ) const;

同時 cv::copyTo() 被重載了,聲明如下:

/** @overload
@param m Destination matrix. If it does not have a proper size or type before the operation, it is reallocated.
@param mask Operation mask of the same size as \*this. Its non-zero elements indicate which matrix elements need to be copied. The mask has to be of type CV_8U and can have 1 or multiple channels.
*/
void copyTo( OutputArray m, InputArray mask ) const;

可以看到重載處註釋:第二個參數 mask 的尺寸與原圖像相同,它的非零元素表示需要複製的矩陣元素,mask 必須是 CV_8U 類型的,可以有 1 個或多個通道。

測試

下圖是兩張 1000*1000 的圖像

在這裏插入圖片描述

在這裏插入圖片描述

目標是將兩張圖像疊在一起,同時在第一張圖像中的白色圓形區域內複製第二張圖像的對應區域,即完成圖像融合,形成如下效果。

在這裏插入圖片描述

由於 cv::copyTo 可以複製將 mask 矩陣中的非零元素的位置對應於原圖像中該位置的值,從而可以實現圖像融合,代碼如下:

#include <iostream>
#include <sstream>
#include <fstream>

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/imgcodecs/imgcodecs.hpp>
#include <opencv2/highgui/highgui.hpp>

#define background "0_background.png"
#define foreground "HappyFish.jpg"

void image_fusion1(cv::Mat& matBackGround, cv::Mat& matForeGround, cv::Mat& matFusion);

int main(int argc, char** argv)
{
	cv::Mat matBackGround;
	cv::Mat matForeGround;

	cv::Mat matFusion;

	image_fusion1(matBackGround, matForeGround, matFusion);

	return 0;
}

void image_fusion1(cv::Mat& matBackGround, cv::Mat& matForeGround, cv::Mat& matFusion)
{
	matBackGround = cv::imread(cv::samples::findFile(background), cv::IMREAD_COLOR);
	matForeGround = cv::imread(cv::samples::findFile(foreground), cv::IMREAD_COLOR);

	//cv::namedWindow("Background", cv::WINDOW_AUTOSIZE);
	//cv::namedWindow("Foreground", cv::WINDOW_AUTOSIZE);
	//cv::namedWindow("Image Fusion", cv::WINDOW_AUTOSIZE);

	matForeGround.copyTo(matFusion, matBackGround);

	cv::imshow("Background", matBackGround);
	cv::imshow("Foreground", matForeGround);
	cv::imshow("Image Fusion", matFusion);

	cv::imwrite("Image Fusion.png", matFusion);

	cv::waitKey(0);
}


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