5. 图像混合

理论-线性混合操作、相关API(addWeighted)

理论-线性混合操作

用到的公式 (其中 α 的取值范围为0~1之间)

相关API(addWeighted)

参数1:输入图像Mat – src1

参数2:输入图像src1的alpha值

参数3:输入图像Mat – src2

参数4:输入图像src2的alpha值

参数5:gamma值

参数6:输出混合图像

注意点:两张图像的大小和类型必须一致才可以

代码演示

#include <opencv2/opencv.hpp>
#include <iostream> using namespace std;
using namespace cv; int main(int argc, char** argv) {
Mat src1, src2, dest;
src1 = imread("D:/vcprojects/images/LinuxLogo.jpg");
src2 = imread("D:/vcprojects/images/win7logo.jpg");
if (!src1.data) {
printf("could not load LinuxLogo image...\n");
return -1;
}
if (!src2.data) {
printf("could not load win7logo image...\n");
return -1;
}
if (src1.rows == src2.rows && src1.cols == src2.cols) {
double alpha = 0.5;
namedWindow("line-blend", CV_WINDOW_AUTOSIZE);
addWeighted(src1, (1 - alpha), src2, alpha, 0.0, dest); imshow("line-blend", dest);
waitKey(0);
return 0;
}
else {
printf("image size is not same...\n");
return -1;
}
}

6. 调整图像亮度与对比度

理论

图像变换可以看作如下:

  • 像素变换 – 点操作

  • 邻域操作 – 区域

    调整图像亮度和对比度属于像素变换 - 点操作

重要的api

  • Mat new_image = Mat::zeros( image.size(), image.type() ); 创建一张跟原图像大小和类型一致的空白图像、像素值初始化为0
  • saturate_cast<uchar>(value)确保值大小范围为0~255之间
  • Mat.at<Vec3b>(y,x)[index]=value 给每个像素点每个通道赋值

代码演示

#include <opencv2/opencv.hpp>
#include <iostream> using namespace cv;
int main(int argc, char** argv) {
Mat src, dst;
src = imread("D:/vcprojects/images/test.png");
if (!src.data) {
printf("could not load image...\n");
return -1;
}
char input_win[] = "input image";
cvtColor(src, src, CV_BGR2GRAY);
namedWindow(input_win, CV_WINDOW_AUTOSIZE);
imshow(input_win, src); // contrast and brigthtness changes
int height = src.rows;
int width = src.cols;
dst = Mat::zeros(src.size(), src.type());
float alpha = 1.2;
float beta = 30; Mat m1;
src.convertTo(m1, CV_32F);
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
if (src.channels() == 3) {
float b = m1.at<Vec3f>(row, col)[0];// blue
float g = m1.at<Vec3f>(row, col)[1]; // green
float r = m1.at<Vec3f>(row, col)[2]; // red // output
dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b*alpha + beta);
dst.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(g*alpha + beta);
dst.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r*alpha + beta);
}
else if (src.channels() == 1) {
float v = src.at<uchar>(row, col);
dst.at<uchar>(row, col) = saturate_cast<uchar>(v*alpha + beta);
}
}
} char output_title[] = "contrast and brightness change demo";
namedWindow(output_title, CV_WINDOW_AUTOSIZE);
imshow(output_title, dst); waitKey(0);
return 0;
}

7. 绘制形状与文字

使用cv::Point与cv::Scalar、绘制线、矩形、园、椭圆等基本几何形状、随机生成与绘制文本

使用cv::Point与cv::Scalar

  • Point表示2D平面上一个点x,y

    Point p;
    p.x = 10;
    p.y = 8;
    or
    p = Pont(10,8);
  • Scalar表示四个元素的向量

    Scalar(a, b, c);// a = blue, b = green, c = red表示RGB三个通道

绘制线、矩形、园、椭圆等基本几何形状

  • 画线 cv::line (LINE_4\LINE_8\LINE_AA)
  • 画椭圆cv::ellipse
  • 画矩形cv::rectangle
  • 画圆cv::circle
  • 画填充cv::fillPoly

随机数生成cv::RNG

  • 生成高斯随机数gaussian (double sigma)
  • 生成正态分布随机数uniform (int a, int b)

绘制添加文字

putText函数 中设置fontFace(cv::HersheyFonts)

​ fontFace, CV_FONT_HERSHEY_PLAIN

​ fontScale , 1.0, 2.0~ 8.0

代码演示

#include <opencv2/opencv.hpp>
#include <iostream> using namespace std;
using namespace cv;
Mat bgImage;
const char* drawdemo_win = "draw shapes and text demo";
void MyLines();
void MyRectangle();
void MyEllipse();
void MyCircle();
void MyPolygon();
void RandomLineDemo();
int main(int argc, char** argv) {
bgImage = imread("D:/vcprojects/images/test1.png");
if (!bgImage.data) {
printf("could not load image...\n");
return -1;
}
//MyLines();
//MyRectangle();
//MyEllipse();
//MyCircle();
//MyPolygon(); //putText(bgImage, "Hello OpenCV", Point(300, 300), CV_FONT_HERSHEY_COMPLEX, 1.0, Scalar(12, 23, 200), 3, 8);
//namedWindow(drawdemo_win, CV_WINDOW_AUTOSIZE);
//imshow(drawdemo_win, bgImage); RandomLineDemo();
waitKey(0);
return 0;
} void MyLines() {
Point p1 = Point(20, 30);
Point p2;
p2.x = 400;
p2.y = 400;
Scalar color = Scalar(0, 0, 255);
line(bgImage, p1, p2, color, 1, LINE_AA);
} void MyRectangle() {
Rect rect = Rect(200, 100, 300, 300);
Scalar color = Scalar(255, 0, 0);
rectangle(bgImage, rect, color, 2, LINE_8);
} void MyEllipse() {
Scalar color = Scalar(0, 255, 0);
ellipse(bgImage, Point(bgImage.cols / 2, bgImage.rows / 2), Size(bgImage.cols / 4, bgImage.rows / 8), 90, 0, 360, color, 2, LINE_8);
} void MyCircle() {
Scalar color = Scalar(0, 255, 255);
Point center = Point(bgImage.cols / 2, bgImage.rows / 2);
circle(bgImage, center, 150, color, 2, 8);
} void MyPolygon() {
Point pts[1][5];
pts[0][0] = Point(100, 100);
pts[0][1] = Point(100, 200);
pts[0][2] = Point(200, 200);
pts[0][3] = Point(200, 100);
pts[0][4] = Point(100, 100); const Point* ppts[] = { pts[0] };
int npt[] = { 5 };
Scalar color = Scalar(255, 12, 255); fillPoly(bgImage, ppts, npt, 1, color, 8);
} void RandomLineDemo() {
RNG rng(12345);
Point pt1;
Point pt2;
Mat bg = Mat::zeros(bgImage.size(), bgImage.type());
namedWindow("random line demo", CV_WINDOW_AUTOSIZE);
for (int i = 0; i < 100000; i++) {
pt1.x = rng.uniform(0, bgImage.cols);
pt2.x = rng.uniform(0, bgImage.cols);
pt1.y = rng.uniform(0, bgImage.rows);
pt2.y = rng.uniform(0, bgImage.rows);
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
if (waitKey(50) > 0) {
break;
}
line(bg, pt1, pt2, color, 1, 8);
// 生成随机彩线
imshow("random line demo", bg);
}
}
#include <opencv2/opencv.hpp>
#include <iostream> using namespace cv;
static const char WINTITLE[] = "randomlines-demo"; int drawRandomLines(Mat image) {
RNG rng(0xffffff);
Point pt1, pt2;
for (int i = 0; i < 100000; i++) {
pt1.x = rng.uniform(0, image.cols);
pt2.x = rng.uniform(0, image.cols);
pt1.y = rng.uniform(0, image.rows);
pt2.y = rng.uniform(0, image.rows);
int r = rng.uniform(0, 255);
int g = rng.uniform(0, 255);
int b = rng.uniform(0, 255);
line(image, pt1, pt2, Scalar(b, g, r), 1, LINE_8);
// 添加文本
putText(image, "Open CV Core Tutorial", Point(image.cols / 2-200, image.rows / 2),
CV_FONT_HERSHEY_PLAIN, 2.0, Scalar(0, 255, 0), 3, LINE_8); imshow(WINTITLE, image);
if (waitKey(10) >= 0)
{
return -1;
}
}
return 0;
} int main(int argc, char** argv) {
Mat image = Mat::zeros(Size(450, 450), CV_8UC3);
namedWindow(WINTITLE, CV_WINDOW_AUTOSIZE);
int ok = drawRandomLines(image);
if (ok != 0) {
return 0;
}
return 0;
}

openCV - 5~7 图像混合、调整图像亮度与对比度、绘制形状与文字的更多相关文章

  1. 跟我一起学opencv 第五课之调整图像亮度和对比度

    一.调整图像亮度与对比度 1.图像变换 ---像素变换-点操作 ---邻域操作-区域操作 调整图像亮度和对比度属于像素变换-点操作 公式为:g(i,j) = αf(i,j) + β 其中α>0 ...

  2. opencv::调整图像亮度与对比度

    图像变换可以看作如下: - 像素变换 – 点操作 - 邻域操作 – 区域 调整图像亮度和对比度属于像素变换-点操作 //创建一张跟原图像大小和类型一致的空白图像.像素值初始化为0 Mat new_im ...

  3. opencv 3 core组件进阶(2 ROI区域图像叠加&图像混合;分离颜色通道、多通道图像混合;图像对比度,亮度值调整)

    ROI区域图像叠加&图像混合 #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp&g ...

  4. opencv学习笔记-图像叠加、混合

    在图像处理中,目标区域定义为感兴趣区域ROI(region of Interest),这是后期图像处理的基础,在获取ROI后,进行一些列的处理.ROI区域在Opencv中就是Rect,先构建Rect, ...

  5. 学习 opencv---(3) ROI 区域图像叠加&初级图像混合

    在这篇文章里,我们一起学习了在OpenCV中如何定义感兴趣区域ROI,如何使用addWeighted函数进行图像混合操作,以及将ROI和addWeighted函数结合起来使用,对指定区域进行图像混合操 ...

  6. 【】opencv窗口创建、大小调整等问题

    opencv窗口创建.大小调整等问题 图像最开始大小可能为1280*720或者其他大小的: 使用cv::resizeWindow函数之后,不同的参数感觉窗口大小没有多少改变,看不出来: 使用cv::s ...

  7. TensorFlow 图像预处理(一) 图像编解码,图像尺寸调整

    from: https://blog.csdn.net/chaipp0607/article/details/73029923 TensorFlow提供了几类图像处理函数,下面介绍图像的编码与解码,图 ...

  8. Atitti 图像处理 图像混合 图像叠加 blend 原理与实现

    Atitti 图像处理 图像混合 图像叠加 blend 原理与实现 混合模式 编辑 本词条缺少信息栏,补充相关内容使词条更完整,还能快速升级,赶紧来编辑吧! 混合模式是图像处理技术中的一个技术名词,不 ...

  9. opencv提取截获图像(总结摘来)

    opencv提取截获图像(总结摘来) http://blog.csdn.net/wuxiaoyao12/article/details/7305865 版权声明:本文为博主原创文章,未经博主允许不得转 ...

随机推荐

  1. luogu P2525 Uim的情人节礼物 其之壱

    LINK:Uim的情人节礼物·其之壱 壱 古代通壹 常在日文中出现. 完全可以使用STL -->prev_permutation来解决. 不过我简单了解了一下康托展开. 这是一个一个排列对应一个 ...

  2. ORACLE不完成恢复ORA-00392,ORA-00312,ORA-00349

    背景: 进行测试库不完全恢复,log_file_name_convert没调整好.rac-asm至单实例-文件系统,recover完成后,mount状态的database  执行 alter data ...

  3. java开发-flyway

    数据库版本管理工具 什么是数据库版本管理? 做过开发的小伙伴们都知道,实现一个需求时,一般情况下都需要设计到数据库表结构的修改.那么我们怎么能保证项目多人开发时,多个数据库环境(测试,生产环境)能够保 ...

  4. AutoMapper 9.0的改造

    AutoMapper于2019.8.12升级9.0 从此不再支持静态的对象转换 自己琢磨了一下,写了一套扩展 官方链接如下 https://github.com/AutoMapper/AutoMapp ...

  5. 【Python 实例】回文数判断

    [Python 实例]回文数判断 题目: 源代码: 运行结果: 题目: 判断输入的字符串是否为回文数 源代码: """ string_reverse_output():反 ...

  6. 自身写Android组合多个布局的经历

    今天不总结课程了,留着有时间补上. 今天的是ExpandListView,就是可以扩展的列表视图. 今天我做了个总结,然后模仿了扣扣的聊天界面,仅仅写了三个页面而已,用到的xml和活动就不下于10个, ...

  7. 《Head First 设计模式》:命令模式

    正文 一.定义 命令模式将"请求"封装成对象(命令对象),以便使用不同的"请求"来参数化其他对象. 要点: 命令模式可将"动作的请求者"从& ...

  8. C#LeetCode刷题之#104-二叉树的最大深度​​​​​​​(Maximum Depth of Binary Tree)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/4072 访问. 给定一个二叉树,找出其最大深度. 二叉树的深度为根 ...

  9. C#图解教程(第四版)—03—类和继承

    1 使用基类的引用 派生类的实例由  基类的实例   加上  派生类 新增的成员 组成. 派生类的  引用   指向整个类对象,包括基类部分 重点:使用对象的  基类部分的引用  来访问对象   (父 ...

  10. Golang并发编程基础

    硬件 内存 作为并发编程一个基础硬件知识储备,首先要说的就是内存了,总的来说在绝大多数情况下把内存的并发增删改查模型搞清楚了其他的基本上也是异曲同工之妙. 内存芯片--即我们所知道的内存颗粒,是一堆M ...