1. 程式人生 > >PNG透明圖片疊加(Opencv實現,包括旋轉縮放以及邊界處理)

PNG透明圖片疊加(Opencv實現,包括旋轉縮放以及邊界處理)

疊加效果

原圖


疊加圖片


大致實現了一個四通道的PNG向量圖疊加到一個三通道的圖片上,函式如下:

bool 疊加(cv::Mat &dst, cv::Mat &src,
double scale = 1.0, //整體透明度
double size = 1.0,//圖片縮放比例
double angle = 0,//圖片旋轉角度
cv::Point location = cv::Point(0, 0)//圖片位置
)

使用示例

#include <opencv2/opencv.hpp>  
#include "疊加.h" 
using namespace cv;
int main()
{
	Mat img1 = imread("timg.jpg"), img2 = imread("img.png", -1);
	imshow("原圖", img1);
	疊加(img1, img2,1,0.4,45,Point(160,220));
	imshow("疊加元素", img2);
	imshow("組合圖", img1);
	waitKey(0);
	return 0;
}



標頭檔案

疊加.h

#pragma once
#include <opencv2/opencv.hpp>  
#include <vector>  
//#include<iostream>

bool 疊加(cv::Mat &dst, cv::Mat &src,
	double scale = 1.0, //整體透明度
	double size = 1.0,//圖片縮放比例
	double angle = 0,//圖片旋轉角度
	cv::Point location = cv::Point(0, 0)//圖片位置

)
{
	if (dst.channels() != 3 || src.channels() != 4 || location.x>dst.cols || location.y>dst.cols)
	{
		return false;
	}


	cv::Mat small_size = src.clone();

	if (size != 1 || angle != 0) {
		int width = src.cols>(dst.cols - location.x) ? (dst.cols - location.x) : src.cols;
		int length = src.rows>(dst.rows - location.y) ? (dst.rows - location.y) : src.rows;
		cv::Mat rotation = cv::getRotationMatrix2D(cv::Point2f(length / 2, width / 2), angle, size);
		cv::warpAffine(small_size, small_size, rotation, cv::Size(width, length));
	}
	//imshow("test", small_size);
	//std::cout << small_size.cols << " " << small_size.rows << std::endl;
	cv::Mat dst_part(dst, cv::Rect(location.x, location.y, small_size.cols, small_size.rows));

	std::vector<cv::Mat>src_channels;
	std::vector<cv::Mat>dst_channels;
	split(small_size, src_channels);
	split(dst_part, dst_channels);
	//	CV_Assert(src_channels.size() == 4 && dst_channels.size() == 3);

	if (scale < 1)
	{
		src_channels[3] *= scale;
		scale = 1;
	}
	for (int i = 0; i < 3; i++)
	{
		dst_channels[i] = dst_channels[i].mul(255.0 / scale - src_channels[3], scale / 255.0);
		dst_channels[i] += src_channels[i].mul(src_channels[3], scale / 255.0);
	}
	merge(dst_channels, dst_part);
	return true;
}


整體打包見地址

提前狗年祝元宵節快樂,233