c++ opencv添加logo_c++调用opencv实现图片叠加以及添加水印效果
前言
本篇文章参考了以下文章:
素材
demo例子起码用到了几个素材,在这里下载:
logo_pc.png
005.jpg
转存失败
underlay.png
overlay.png
转存失败
test.png
代码
头文件:
#ifndef DEMO_IMAGEMIX_H
#define DEMO_IMAGEMIX_H
#include
#include "opencv2/opencv.hpp"
#include "opencv2/core.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgcodecs.hpp"
#include
#include
#include
using namespace cv;
using namespace std;
class Demo_ImageMix
{
public:
Demo_ImageMix();
void mix1(std::string orgImg, std::string logoPic,double alphaValue);
void mix2(std::string orgImg, std::string logoPic,double alphaValue);
int MakeWatermarkTest(
std::string underlayPic,
std::string overlayPic,
std::string testPic);
int MakeWatermark(
std::string underlayPic,
std::string overlayPic
,double alphaValue
);
private:
void overlayImage(Mat* src, Mat* overlay, const Point& location);
};
#endif // DEMO_IMAGEMIX_H
cpp源文件:
#include "demo_imagemix.h"
/***
* 该class用于演示
* 1、两张图片叠加包含 透明 效果
* 2、底图上面添加png图片水印【水印背景透明】
**/
Demo_ImageMix::Demo_ImageMix()
{
}
/**
任意图片叠加
**/
void Demo_ImageMix::mix1(std::string orgImg, std::string logoPic,double alphaValue){
//两图像的权值
// double alphaValue = 0.3;
// alphaValue=0.5;
double betaValue = 1 - alphaValue;
/**
整体思路:
1、分别读取两张图片,然后根据图片尺寸创建一个新的能够容纳两张图片.
2、在底图上面获取logo对应区域
3、logo_img与没有东西的imgPart4Logo混合,得到有透明度的结果图片:dstImage
5、dstImage复制到imgPart4logo区域上面。--因为直接在底图上面操作的,这时候应该已经改变了。
6、显示结果图片 image_src
**/
Mat image_src=cv::imread(orgImg,1);
cv::Mat logo_img=cv::imread(logoPic,1);
Mat imgPart4logo=image_src(Rect(0,0,logo_img.cols,logo_img.rows));
Mat dstImage;
cv::addWeighted(logo_img, alphaValue, imgPart4logo,
betaValue, 0.0,
dstImage);
dstImage.copyTo(imgPart4logo);
cv::imshow("result",image_src);
waitKey(0);
return;
}
/**
任意图片叠加
https://blog.csdn.net/mars_xiaolei/article/details/78791133
*@param alphaValue logo图片的透明度
**/
void Demo_ImageMix::mix2(std::string orgImg, std::string logoPic,double alphaValue){
//两图像的权值
// double alphaValue = 0.3;
// alphaValue=0.5;
double betaValue = 1 - alphaValue;
/**
整体思路:
1、分别读取两张图片,然后根据图片尺寸创建一个新的能够容纳两张图片最大宽度与最大高度的mat对象--img_merge
2、分别在img_merge上面取src以及logo两个图片区域
3、image_src先复制到对应的img_merge区域上面
4、logo_img与没有东西的imgPart4Logo混合,得到有透明度的结果图片:dstImage
5、dstImage复制到imgPart4logo区域上面。
6、显示结果图片 img_merge
**/
Mat image_src=cv::imread(orgImg,1);
cv::Mat logo_img=cv::imread(logoPic,1);
Mat img_merge;
cv::Size size(MAX(image_src.cols,logo_img.cols),MAX(image_src.rows,logo_img.rows));
img_merge.create(size,CV_MAKETYPE(image_src.depth(),3));
img_merge=Scalar::all(0);
Mat imgPart4Src=img_merge(Rect(0,0,image_src.cols,image_src.rows));
Mat imgPart4logo=img_merge(Rect(0,0,logo_img.cols,logo_img.rows));
image_src.copyTo(imgPart4Src);
/***
****/
//logo_img.copyTo(imgPart4logo);
Mat dstImage;
cv::addWeighted(logo_img, alphaValue, imgPart4logo,
betaValue, 0.0,
dstImage);
dstImage.copyTo(imgPart4logo);
cv::imshow("result",img_merge);
waitKey(0);
return;
}
/***
光是看这个函数就像是在 合并两张图片的某个通道的值。。。
https://answers.opencv.org/question/73016/how-to-overlay-an-png-image-with-alpha-channel-to-another-png/
**/
void Demo_ImageMix::overlayImage(Mat* src, Mat* overlay, const Point& location)
{
for (int y = max(location.y, 0); y rows; ++y)
{
int fY = y - location.y;
if (fY >= overlay->rows)
break;
for (int x = max(location.x, 0); x cols; ++x)
{
int fX = x - location.x;
if (fX >= overlay->cols)
break;
double opacity = ((double)overlay->data[fY * overlay->step + fX * overlay->channels() + 3]) / 255;
for (int c = 0; opacity > 0 && c channels(); ++c)
{
unsigned char overlayPx = overlay->data[fY * overlay->step + fX * overlay->channels() + c];
unsigned char srcPx = src->data[y * src->step + x * src->channels() + c];
src->data[y * src->step + src->channels() * x + c] = srcPx * (1. - opacity) + overlayPx * opacity;
}
}
}
}
/**
打水印
https://answers.opencv.org/question/73016/how-to-overlay-an-png-image-with-alpha-channel-to-another-png/
**/
int Demo_ImageMix::MakeWatermarkTest(
std::string underlayPic,
std::string overlayPic,
std::string testPic){
Mat underlay = imread(underlayPic,IMREAD_UNCHANGED);
Mat overlay = imread(overlayPic,IMREAD_UNCHANGED);
Mat test = imread(testPic,IMREAD_UNCHANGED);
if( underlay.empty() || overlay.empty() || test.empty() )
{
cout <
return -1;
}
Mat rgba[4];
split(underlay,rgba);
imshow("alpha1.png",rgba[3]);
imwrite("alpha1.png",rgba[3]);
split(overlay,rgba);
imshow("alpha2.png",rgba[3]);
imwrite("alpha2.png",rgba[3]);
overlayImage( &underlay, &overlay, Point() );
overlayImage( &test, &underlay, Point(120,180) );
split(underlay,rgba);
imshow("alpha3.png",rgba[3]);
imwrite("alpha3.png",rgba[3]);
imshow("result1",underlay);
imwrite("result1.png",underlay);
imshow("result2",test);
imwrite("result2.png",test);
waitKey();
return 0;
}
/***
在原有基础上顺便加一个透明度。
**/
int Demo_ImageMix::MakeWatermark(
std::string underlayPic,
std::string overlayPic
,double alphaValue
){
Mat underlay = imread(underlayPic,IMREAD_UNCHANGED);
Mat overlay = imread(overlayPic,IMREAD_UNCHANGED);
double betaValue = 1 - alphaValue;
if( underlay.empty() || overlay.empty() )
{
cout <
return -1;
}
//--处理透明度
Mat dstImage;
Mat img_merge;
cv::Size size(overlay.cols,overlay.rows);
//--!!!注意,png图片应该是四通道的,jpg应该是3通道的,如果这里设置为3通道,那么跟overlay图片运算时候就会出问题。
img_merge.create(size,CV_MAKETYPE(overlay.depth(),4));
img_merge=Scalar::all(0);
Mat imgPart4OverLay=img_merge(Rect(0,0,overlay.cols,overlay.rows));
cv::addWeighted(overlay, alphaValue, imgPart4OverLay,
betaValue, 0.0,
dstImage);
Mat rgba[4];
imshow("添加透明度之后的logo图片",dstImage);
overlayImage( &underlay, &dstImage, Point() );
imshow("打水印结果",underlay);
waitKey();
return 0;
}
入口函数 main.cpp
#include
#include
#include "demo_imagemix.h"
using namespace std;
static const std::string LogoPcPath="/home/too-white/temp/logo_pc.png";
static const std::string DemoImage005 = "/home/too-white/temp/005.jpg";
static const std::string DemoUnderLayImage = "/home/too-white/temp/underlay.png";
static const std::string DemoOverlayImage = "/home/too-white/temp/overlay.png";
static const std::string DemoTestLayImage = "/home/too-white/temp/test.png";
int checkFileEsits(std::string & filePath){
fstream file;
file.open(filePath.data(),
ios::in);
if(file.fail()){
file.close();
return 0;
}
file.close();
return 1;
}
int main(){
std::cout<
Demo_ImageMix imgMix;
//imgMix.mix1(DemoImage005,LogoPcPath,0.5);
//imgMix.MakeWatermarkTest(DemoUnderLayImage,LogoPcPath,DemoImage005);
imgMix.MakeWatermark(DemoImage005,LogoPcPath,0.5);
return 0;
}
测试结果
注意,测试的时候只执行了
mix1【与mix2的结果是一样的,只是写法不一样】,MakeWaterMarkTest与MakeWaterMark三个方法,下面是结果:
mix1:
两张图片叠加的效果是---真的是叠加啊。。。
MakeWaterMarkTest:
转存失败
看到这个结果,感觉就是合并其中一条通道实现效果的。
MakeWaterMark:
转存失败
可以设置透明度的水印,这个实用价值才大。。
我。。。老是提示转存失败,原素材可以到下面拿:
c++ opencv添加logo_c++调用opencv实现图片叠加以及添加水印效果相关推荐
- c++调用opencv实现图片叠加以及添加水印效果
前言 本篇文章参考了以下文章: https://blog.csdn.net/mars_xiaolei/article/details/78791133 https://answers.opencv.o ...
- php 图片裁剪保存,PHP实现图片裁剪、添加水印效果代码
这篇文章主要介绍了PHP实现图片裁剪.添加水印效果代码,本文给出代码示例,代码中包含一些说明注释,需要的朋友可以参考下 3.PHP对图像的裁剪 裁剪之前 header("content-ty ...
- Android仿拼多多实现图片叠加部分覆盖效果
Android仿拼多多实现图片叠加部分覆盖效果 需要实现的效果如下: 代码部分: AppIconStackView: public class AppIconStackView extends Vie ...
- matlab调用opencv库,matlab调用opencv库
matlab中有许多图像处理的函数简单方便,比如矩阵x 求垂直积分 直接sum(x) 就可以了.不知道OPENCV里面有没有类似的功能,反正我是没找到.就准备用matlab调用OPENCV里面的函数. ...
- python调用opencv代码_Python调用OpenCV实现图像平滑代码实例
主要讲解Python调用OpenCV实现图像平滑,包括四个算法:均值滤波.方框滤波.高斯滤波和中值滤波. 给图像增加噪声: import cv2 import numpy as np def test ...
- c++ opencv添加logo_关于opencv对图片添加水印
有一段时间没有写博客了,最近因为自己需要给图片添加水印,就写了个简单的图片添加水印 python:3.6.7 pycharm opencv是一个开源的库,是有C++编写,支持C ++,Python,J ...
- Shader学习12——简易图片叠加
看到蛮牛有人想要两个带透明通道的图片叠加,就是最简单的纹理混合,想想其实实现起来应该很简单,但是搜了一下还真没搜到,这里简单实现一下,要求底图需要是不透明的: image.png image.png ...
- OpenCV添加中文(五)
OpenCV添加文字的方法putText(-),添加英文是没有问题的,但如果你要添加中文就会出现"???"的乱码,需要特殊处理一下. 下文提供封装好的(代码)方法,供OpenCV添 ...
- python+opencv 问题解决方案,OpenCV Error: Unspecified error (The function is not implemented. Rebuild the
解决方法:用以下方式安装opencv pip install opencv-python 以下转载自:https://blog.csdn.net/fdd096030079/article/detail ...
- csharp通过dll调用opencv函数,图片作为参数
[blog 项目实战派]csharp通过dll调用opencv函数,图片作为参数 一直想做着方面的研究,但是因为这个方面的知识过于小众,也是由于自己找资料的能力比较弱,知道今天才找 ...
最新文章
- 小程序聊天室开发,发送文字,表情,图片,音频,视频,即时通讯,快速部署,可定制开发
- CXF做的webservice简单例子
- 《图解HTTP》读书笔记(四:HTTP方法)
- SSE命令示例代码(算术、逻辑、比较)
- kernel 3.10内核源码分析--中断--中断和异常返回流程
- centos安装vsftp后的虚拟用户设置
- linux远程windows执行cmd,Linux服务器远程连接window服务器并执行cmd命令
- EasyARM-iMX283A的Linux 开发环境构建
- web command line : http://yubnub.org/
- Delphi 取整函数round、trunc、ceil和floor
- 解决win10 蓝牙设备只能配对无法连接 ,并且删除设备无效的问题
- linux下的hosts文件
- win10 安装gym[all]与mujoco的踩坑日志
- 前端用JS + SVG 实现关系图谱 流程图
- 笔记本无线上网卡怎么用?
- 基于微信小程序的毕业设计题目(34)PHP小说平台小程序(含开题报告、任务书、中期报告、答辩PPT、论文模板)
- 机器人系统仿真(七)——xacro语法详解
- 外贸邮箱企业邮箱,免费外贸企业邮箱大全,外贸企业邮箱都有哪些?
- sdutOJ 查字典(Python)
- Android神兵利器之Image Asset Studio