opencv 打开图片后,cv::mat存入共享内存的代码,以及如何设置共享内存的大小?图片的3840x2160 pixels

本文主要是介绍opencv 打开图片后,cv::mat存入共享内存的代码,以及如何设置共享内存的大小?图片的3840x2160 pixels,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

opencv 打开图片后,cv::mat存入共享内存的代码,以及如何设置共享内存的大小?图片的3840x2160 pixels。
在OpenCV中,将cv::Mat对象存入共享内存需要几个步骤。首先,你需要创建一个共享内存区域,然后将cv::Mat的数据复制到该区域。下面是一个简单的示例代码,展示了如何实现这一过程:

  • 创建共享内存区域:你可以使用POSIX共享内存(shm_open和mmap)或System V共享内存(shmget和shmat)来创建共享内存区域。这里我们使用POSIX共享内存作为例子。
  • 设置共享内存的大小:共享内存的大小应该至少与cv::Mat的数据部分一样大。对于彩色图像,每个像素通常由多个字节表示(例如,对于BGR图像,每个像素有3个字节)。此外,还需要考虑图像的行对齐(stride)问题。OpenCV的cv::Mat对象可能包含额外的填充字节以确保每行的起始地址对齐。

下面是一个简单的代码示例:

#include <opencv2/opencv.hpp>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>int main() {// 读取图片cv::Mat image = cv::imread("path_to_your_image.jpg", cv::IMREAD_COLOR);if (image.empty()) {std::cerr << "无法打开图片" << std::endl;return -1;}// 计算共享内存的大小// 对于BGR图像,每个像素3个字节,加上可能的行对齐填充size_t shmSize = image.total() * image.elemSize() + getpagesize() - 1;shmSize -= shmSize % getpagesize(); // 确保大小是页面大小的整数倍// 创建共享内存对象int shmFd = shm_open("/my_shared_memory", O_CREAT | O_RDWR, 0666);if (shmFd == -1) {perror("shm_open");return -1;}// 设置共享内存的大小if (ftruncate(shmFd, shmSize) == -1) {perror("ftruncate");return -1;}// 将共享内存映射到进程的地址空间void* shmPtr = mmap(nullptr, shmSize, PROT_READ | PROT_WRITE, MAP_SHARED, shmFd, 0);if (shmPtr == MAP_FAILED) {perror("mmap");return -1;}// 将cv::Mat的数据复制到共享内存memcpy(shmPtr, image.data, image.total() * image.elemSize());// ... 在这里,你可以让其他进程访问共享内存中的图像数据 ...// 清理资源munmap(shmPtr, shmSize);close(shmFd);shm_unlink("/my_shared_memory");return 0;
}

注意:

上述代码仅作为示例,可能需要根据你的具体需求进行调整。
共享内存的使用需要谨慎处理同步和互斥问题,以避免数据竞争和不一致。你可能需要使用锁或其他同步机制来确保多个进程安全地访问共享内存。
在使用共享内存时,还需要考虑权限和安全性问题。确保只有授权的进程可以访问共享内存,并遵循最小权限原则。

为何不用read() 用memcpy()?

在涉及共享内存时,使用 memcpy() 而不是 read() 的主要原因在于共享内存的特性。共享内存允许两个或多个进程直接访问同一块物理内存,而不需要通过内核或其他中间层进行数据的复制或传递。

直接访问:由于共享内存是直接映射到每个进程的地址空间的,因此进程可以像访问本地内存一样直接访问它。这意味着进程可以直接读取和写入共享内存,而不需要通过系统调用(如 read() 或 write())来间接操作。
效率:使用 memcpy() 直接在进程的地址空间内复制数据通常比使用 read() 或 write() 进行系统调用要快得多。系统调用涉及内核与用户空间之间的上下文切换,这通常是一个相对昂贵的操作。因此,对于需要频繁访问共享内存的场景,使用 memcpy() 可以显著提高性能。
语义差异:read() 通常用于从文件描述符(如文件、管道或套接字)中读取数据,而共享内存不是文件描述符。因此,从语义上讲,使用 memcpy() 来复制共享内存中的数据更为合适。
同步问题:当多个进程同时访问共享内存时,需要考虑同步问题以避免数据竞争和不一致。使用 memcpy() 并不会解决同步问题,但你可以结合其他同步机制(如互斥锁、信号量或原子操作)来确保对共享内存的访问是安全的。

总之,使用 memcpy() 而不是 read() 来访问共享内存是因为共享内存允许直接访问,使用 memcpy() 可以提高性能,并且从语义上讲更为合适。然而,这并不意味着 read() 在所有情况下都不能用于共享内存;在某些特定的上下文中,它可能仍然是有用的。但在大多数情况下,当涉及到共享内存时,你会更倾向于使用 memcpy() 或其他类似的内存操作函数。

为何cv::mat的内存比图片本身大很多?图片只有1.5M,但是内存有25M

cv::Mat对象在内存中占用的空间可能比图片文件本身大很多,这通常是由以下几个原因造成的:

数据格式和编码:图片文件在存储时,通常会使用某种形式的压缩,例如JPEG、PNG等。这些压缩格式可以有效地减小文件大小,但解压后的原始图像数据会占用更多的内存空间。cv::Mat存储的是解压后的原始图像数据,因此其内存占用会大于压缩后的文件大小。

通道和深度:图像的每个像素可能由多个通道组成(如RGB图像的三个通道),每个通道可能使用不同的数据深度(如8位无符号整数、16位有符号整数、32位浮点数等)。通道数量和深度的增加都会导致内存占用的增加。

行对齐:cv::Mat为了优化内存访问速度,可能会在每行的末尾添加额外的填充字节,以确保每行的起始地址都是某个固定大小的整数倍(通常是16字节或32字节)。这种行对齐会增加内存占用,但可以提高内存访问的效率。

附加信息和元数据:除了图像数据本身外,cv::Mat还可能存储一些附加信息和元数据,如图像的尺寸、类型、步长等。这些信息虽然不直接表示图像内容,但也会占用一定的内存空间。

内存分配机制:在某些情况下,内存分配器可能会为cv::Mat分配比实际所需稍大的内存块,以减少频繁分配和释放小块内存的开销。这也会导致观察到的内存占用大于预期。

因此,即使图片文件本身只有1.5M,cv::Mat对象在内存中占用25M也是可能的。这并不意味着有内存浪费,而是反映了原始图像数据在内存中的实际占用情况。如果需要减小内存占用,可以考虑使用更小的数据类型、减少通道数量或采用其他优化方法。然而,这些优化可能会影响到图像的质量和处理能力。

另外一个进程显示

#include <opencv2/opencv.hpp>
#include <sys/mman.h> // 对于共享内存映射
#include <fcntl.h>    // 对于文件控制操作
#include <unistd.h>   // 对于unistd系统调用
#include <cstring>    // 对于memcpy// 假设你已经有了共享内存的标识符(例如,通过shm_open或ftruncate创建)
int shm_fd = ...; // 共享内存的文件描述符// 假设你已经知道了图片的尺寸和类型
int width = ...;
int height = ...;
int channels = ...; // 例如,对于BGR图片,channels是3
int type = CV_8UC3; // 假设是8位无符号字符的3通道BGR图片// 计算共享内存的大小
size_t shmSize = width * height * channels * sizeof(uchar);// 将共享内存映射到当前进程的地址空间
uchar* sharedMemoryData = static_cast<uchar*>(mmap(nullptr, shmSize, PROT_READ, MAP_SHARED, shm_fd, 0));
if (sharedMemoryData == MAP_FAILED) {perror("mmap");// 错误处理...
}// 创建cv::Mat对象来包装共享内存中的数据
cv::Mat image(height, width, type, sharedMemoryData);// 显示图片
cv::imshow("Stitching Image", image);
cv::waitKey(0); // 等待按键,0表示无限等待// 在不再需要时,解除映射
if (munmap(sharedMemoryData, shmSize) == -1) {perror("munmap");// 错误处理...
}// 关闭共享内存的文件描述符
close(shm_fd);

个人实践

https://gitee.com/hiyanyx/share-memory-mmap-opencv

这篇关于opencv 打开图片后,cv::mat存入共享内存的代码,以及如何设置共享内存的大小?图片的3840x2160 pixels的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1072829

相关文章

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

opencv 滚动条

参数介绍:createTrackbar( trackbarname , "hello" , &alpha_slider ,alpha_max ,  on_trackbar )  ;在标签中显示的文字(提示滑动条的用途) TrackbarName创建的滑动条要放置窗体的名字 “hello”滑动条的取值范围从 0 到 alpha_max (最小值只能为 zero).滑动后的值存放在

代码随想录冲冲冲 Day39 动态规划Part7

198. 打家劫舍 dp数组的意义是在第i位的时候偷的最大钱数是多少 如果nums的size为0 总价值当然就是0 如果nums的size为1 总价值是nums[0] 遍历顺序就是从小到大遍历 之后是递推公式 对于dp[i]的最大价值来说有两种可能 1.偷第i个 那么最大价值就是dp[i-2]+nums[i] 2.不偷第i个 那么价值就是dp[i-1] 之后取这两个的最大值就是d

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

pip-tools:打造可重复、可控的 Python 开发环境,解决依赖关系,让代码更稳定

在 Python 开发中,管理依赖关系是一项繁琐且容易出错的任务。手动更新依赖版本、处理冲突、确保一致性等等,都可能让开发者感到头疼。而 pip-tools 为开发者提供了一套稳定可靠的解决方案。 什么是 pip-tools? pip-tools 是一组命令行工具,旨在简化 Python 依赖关系的管理,确保项目环境的稳定性和可重复性。它主要包含两个核心工具:pip-compile 和 pip

D4代码AC集

贪心问题解决的步骤: (局部贪心能导致全局贪心)    1.确定贪心策略    2.验证贪心策略是否正确 排队接水 #include<bits/stdc++.h>using namespace std;int main(){int w,n,a[32000];cin>>w>>n;for(int i=1;i<=n;i++){cin>>a[i];}sort(a+1,a+n+1);int i=1