05- OpenCV:图像操作和图像混合

目录

一、图像操作

1、读写图像

2、读写像素

3、修改像素值

4、Vec3b与Vec3F

5、相关的代码演示

二、图像混合

1、理论-线性混合操作

2、相关API(addWeighted)

3、代码演示(完整的例子)


一、图像操作

1、读写图像

(1)imread 可以指定加载为灰度或者RGB图像

(2)Imwrite 保存图像文件,类型由扩展名决定

2、读写像素

(1)读一个GRAY像素点的像素值(CV_8UC1)

Scalar intensity = img.at<uchar>(y, x);
或者 
Scalar intensity = img.at<uchar>(Point(x, y)); 

(2)读一个RGB像素点的像素值

Vec3f intensity = img.at<Vec3f>(y, x);
float blue = intensity.val[0];
float green = intensity.val[1];
float red = intensity.val[2];
3、修改像素值

(1)灰度图像

 img.at<uchar>(y, x) = 128;

(2)RGB三通道图像

img.at<Vec3b>(y,x)[0]=128; // blue 
img.at<Vec3b>(y,x)[1]=128; // green 
img.at<Vec3b>(y,x)[2]=128; // red

(3)空白图像赋值

img = Scalar(0);

(4)ROI选择

Rect r(10, 10, 100, 100); 
Mat smallImg = img(r);
4、Vec3b与Vec3F

(1)Vec3b对应三通道的顺序是blue、green、red的uchar类型数据。

(2)Vec3f对应三通道的float类型数据

(3)把CV_8UC1转换到CV32F1实现如下:

src.convertTo(dst, CV_32F);
5、相关的代码演示
#include <opencv2/core/core.hpp> 
#include <opencv2/imgcodecs.hpp> 
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>using namespace cv;
using namespace std;
int main(int argc, char** args) {Mat image = imread("D:/test.jpg", IMREAD_COLOR);if (image.empty()) {cout << "could not find the image resource..." << std::endl;return -1;}Mat grayImg;cvtColor(image, grayImg, COLOR_BGR2GRAY);Mat sobelx; Sobel(grayImg, sobelx, CV_32F, 1, 0);double minVal, maxVal;minMaxLoc(sobelx, &minVal, &maxVal); //find minimum and maximum intensitiesMat draw;sobelx.convertTo(draw, CV_8U, 255.0 / (maxVal - minVal), -minVal * 255.0 / (maxVal - minVal));/*int height = image.rows;int width = image.cols;int channels = image.channels();printf("height=%d width=%d channels=%d", height, width, channels);for (int row = 0; row < height; row++) {for (int col = 0; col < width; col++) {if (channels == 3) {image.at<Vec3b>(row, col)[0] = 0; // blueimage.at<Vec3b>(row, col)[1] = 0; // green}}}*/namedWindow("My Image", CV_WINDOW_AUTOSIZE);imshow("My Image", draw);waitKey(0);return 0;
}

效果展示:

bitwise_not()这接口使用:逐位取反

#include<opencv2\opencv.hpp>
#include<iostream>using namespace cv;int main()
{Mat src, dst;src = imread("test.jpg");if (!src.data){printf("could not load image...\n");}namedWindow("input image", CV_WINDOW_AUTOSIZE);imshow("input image", src);// 单通道的MatMat gray_src;cvtColor(src, gray_src, COLOR_RGB2GRAY);// 颜色空间的转换int nc = src.channels();// 图像像素操作,取反后,看输出是什么样子for (int row = 0; row < src.rows; row++){for (int col = 0; col < src.cols; col++){if (nc == 1){int gray = gray_src.at<uchar>(row, col);gray_src.at<uchar>(row, col) = 255 - gray;}else if (nc == 3){int b = src.at<Vec3b>(row, col)[0];int g = src.at<Vec3b>(row, col)[1];int r = src.at<Vec3b>(row, col)[2];dst.at<Vec3b>(row, col)[0] = 255 - b;dst.at<Vec3b>(row, col)[1] = 255 - g;dst.at<Vec3b>(row, col)[2] = 255 - r;//取最大值为灰度像素值//gray_src.at<uchar>(row, col) = max(r, max(b, g));//取最小值为灰度像素值//gray_src.at<uchar>(row, col) = min(r, min(b, g));}}}// 最后一个if的操作,就是3色通道的rgb都取反,可以用下面的接口代替//bitwise_not(src, dst);//能实现一样的效果namedWindow("mask_result", CV_WINDOW_AUTOSIZE);imshow("mask_result", dst);//imshow("mask_result", gray_src); //输出灰色图像waitKey(0);return 0;}

运行代码得出最后的效果:

二、图像混合

1、理论-线性混合操作

其中      的取值范围为0~1之间

2、相关API(addWeighted)

addWeighted 是OpenCV中的一个函数,用于对两个图像进行加权相加。它可以用于图像融合、图像混合以及图像叠加等应用。

函数原型如下:


void cv::addWeighted(InputArray src1,double alpha,InputArray src2,double beta,double gamma,OutputArray dst,int dtype = -1)

参数说明:

  • src1:第一个输入图像。
  • alpha:第一个输入图像的权重。
  • src2:第二个输入图像。
  • beta:第二个输入图像的权重。
  • gamma:加到结果上的标量值。
  • dst:输出图像,与输入图像具有相同的尺寸和类型。
  • dtype:可选参数,指定输出图像的数据类型,默认为-1,表示与输入图像保持一致。

关键代码实现


cv::Mat image1 = cv::imread("image1.jpg");
cv::Mat image2 = cv::imread("image2.jpg");cv::Mat blendedImage;
double alpha = 0.5;  // 第一个图像的权重double beta = 0.5;   // 第二个图像的权重double gamma = 0.0;  // 加到结果上的标量值cv::addWeighted(image1, alpha, image2, beta, gamma, blendedImage);cv::imshow("Blended Image", blendedImage);
cv::waitKey(0);

代码将加载两张图像,然后用 addWeighted 函数将它们进行加权相加,并将结果显示在窗口中。

你可以根据实际需求调整 alphabetagamma 的值,以及选择不同的图像作为输入来实现不同的效果。

3、代码演示(完整的例子)
#include <opencv2/opencv.hpp>
#include <iostream>using namespace std;
using namespace cv;int main(int argc, char** argv) {Mat src1, src2, dst;src1 = imread("D:/vcprojects/images/LinuxLogo.jpg");src2 = imread("D:/vcprojects/images/win7logo.jpg");if (!src1.data) {cout << "could not load image Linux Logo..." << endl;return -1;}if (!src2.data) {cout << "could not load image WIN7 Logo..." << endl;return -1;}double alpha = 0.5;if (src1.rows == src2.rows && src1.cols == src2.cols && src1.type() == src2.type()) {// addWeighted(src1, alpha, src2, (1.0 - alpha), 0.0, dst);// multiply(src1, src2, dst, 1.0);imshow("linuxlogo", src1);imshow("win7logo", src2);namedWindow("blend demo", CV_WINDOW_AUTOSIZE);imshow("blend demo", dst);}else {printf("could not blend images , the size of images is not same...\n");return -1;}waitKey(0);return 0;
}

效果如下:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/339552.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

阿赵UE学习笔记——8、贴图导入设置

阿赵UE学习笔记目录 大家好&#xff0c;我是阿赵。   继续学习虚幻引擎的用法&#xff0c;这次来说一下贴图的导入设置。   在内容浏览器里面可以看到纹理类型的资源&#xff0c;就是贴图了&#xff0c;鼠标悬浮在上面可以看到这个纹理贴图的信息&#xff1a; 双击纹理贴图…

基于ssm文化遗产的保护与旅游开发论文

摘 要 信息数据从传统到当代&#xff0c;是一直在变革当中&#xff0c;突如其来的互联网让传统的信息管理看到了革命性的曙光&#xff0c;因为传统信息管理从时效性&#xff0c;还是安全性&#xff0c;还是可操作性等各个方面来讲&#xff0c;遇到了互联网时代才发现能补上自古…

【Python程序开发系列】一文总结程序运行出现No module named ‘xxx‘的解决方案

这是Python程序开发系列原创文章&#xff0c;我的第196篇原创文章。 一、引言 "ModuleNotFoundError: No module named xxx"这个报错是个非常常见的报错&#xff0c;几乎每个python程序员都遇到过&#xff0c;导致这个报错的原因也非常多&#xff0c;解决这个问题之…

原生Camera2中CameraMetadata用法和代码流程详解

1&#xff0c;CameraMetadata介绍 CameraMetadata在Android的Camera2 API中起到了关键的作用。它提供了一种机制&#xff0c;使应用程序能够获取关于相机硬件和其当前状态的元数据。这些元数据包括各种信息&#xff0c;例如相机传感器的状态、镜头的朝向、闪光灯的充电状态、自…

智能AI一键养号,助力账号增加浏览轨迹的全新体验

我想分享一下我对亚马逊鲲鹏系统的智能AI一键养号功能的使用体验。这一创新性的功能让账号的养号过程变得更加轻松、灵活且有效。 首先&#xff0c;我对软件的AI功能页面印象深刻。通过勾选不同的姓名、职业、性别等选项&#xff0c;我可以生成各种不同的AI角色。这些角色使得账…

windows10 装docker和docker compose

一.windows环境准备 开启过程中的问题&#xff0c;进入bios修复 二.docker下载安装 1.下载 Docker Desktop: The #1 Containerization Tool for Developers | Docker 下载最新版有问题&#xff0c;下载老版本试试 Docker Desktop release notes | Docker Docs 2.安装 三.do…

C++11_lambda表达式

文章目录 一、lambda表达式1.lambda的组成2.[capture-list] 的其他使用方法2.1混合捕捉 二、lambda表达式的使用场景1.替代仿函数 总结 一、lambda表达式 lambda表达式是C11新引入的功能&#xff0c;它的用法与我们之前学过的C语法有些不同。 1.lambda的组成 [capture-list] …

有免费仓库出入库管理软件推荐吗?

有免费仓库出入库管理软件推荐吗&#xff1f; 对于希望仓库管理系统“简单易上手”的使用者来说&#xff0c;能够实现扫码出入库的系统无疑是最优选。这种方式以其直观的操作和高效的流程&#xff0c;极大地简化了仓库管理&#xff0c;为用户提供了许多实际的便利。 像我们公…

android 实时流媒体 实时流媒体播放

场景描述 将实时流采集终端的视频数据实时推送到另外一个&#xff08;多个&#xff09;播放终端&#xff0c;完成远距离实时视频播放的功能。典型场景&#xff1a; &#xff08;1&#xff09;远程查看监控摄像头。选择指定摄像头&#xff0c;将该摄像头采集到的实时数据推送到…

k8s的存储卷、数据卷---动态PV创建

当发布PVC之后可以生成PV&#xff0c;还可以在动态服务器上直接生成挂载目录。PVC直接绑定和使用PV。 动态PV需要两个组件 存储卷插件&#xff1a;Provisioner(存储分配器)根据定义的属性创建PV StorageClass&#xff1a;定义属性 存储卷插件 存储卷插件&#xff1a;k8s本…

【谭浩强C程序设计 学习辅导第3章】最简单的C程序设计——顺序程序设计(含详细源码)

文章目录 一、 顺序程序设计题的解题思路及注意事项解题思路注意事项 二、源码讲解第3章源码文件构成&#xff1a;main.c 文件内容说明chap3.c源码实现chap3.h声明头文件测试结果展示源码链接 说明&#xff1a;本学习辅导题适用于谭浩强教辅第四版。 一、 顺序程序设计题的解题…

【数据库】视图索引执行计划多表查询笔试题

文章目录 一、视图1.1 概念1.2 视图与数据表的区别1.3 优点1.4 语法1.5 实例 二、索引2.1 什么是索引2.2.为什么要使用索引2.3 优缺点2.4 何时不使用索引2.5 索引何时失效2.6 索引分类2.6.1.普通索引2.6.2.唯一索引2.6.3.主键索引2.6.4.组合索引2.6.5.全文索引 三、执行计划3.1…