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

相关文章

Java实现将HTML文件与字符串转换为图片

《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H

Java实现在Word文档中添加文本水印和图片水印的操作指南

《Java实现在Word文档中添加文本水印和图片水印的操作指南》在当今数字时代,文档的自动化处理与安全防护变得尤为重要,无论是为了保护版权、推广品牌,还是为了在文档中加入特定的标识,为Word文档添加... 目录引言Spire.Doc for Java:高效Word文档处理的利器代码实战:使用Java为Wo

Redis实现高效内存管理的示例代码

《Redis实现高效内存管理的示例代码》Redis内存管理是其核心功能之一,为了高效地利用内存,Redis采用了多种技术和策略,如优化的数据结构、内存分配策略、内存回收、数据压缩等,下面就来详细的介绍... 目录1. 内存分配策略jemalloc 的使用2. 数据压缩和编码ziplist示例代码3. 优化的

基于C#实现PDF转图片的详细教程

《基于C#实现PDF转图片的详细教程》在数字化办公场景中,PDF文件的可视化处理需求日益增长,本文将围绕Spire.PDFfor.NET这一工具,详解如何通过C#将PDF转换为JPG、PNG等主流图片... 目录引言一、组件部署二、快速入门:PDF 转图片的核心 C# 代码三、分辨率设置 - 清晰度的决定因

Python 基于http.server模块实现简单http服务的代码举例

《Python基于http.server模块实现简单http服务的代码举例》Pythonhttp.server模块通过继承BaseHTTPRequestHandler处理HTTP请求,使用Threa... 目录测试环境代码实现相关介绍模块简介类及相关函数简介参考链接测试环境win11专业版python

Python从Word文档中提取图片并生成PPT的操作代码

《Python从Word文档中提取图片并生成PPT的操作代码》在日常办公场景中,我们经常需要从Word文档中提取图片,并将这些图片整理到PowerPoint幻灯片中,手动完成这一任务既耗时又容易出错,... 目录引言背景与需求解决方案概述代码解析代码核心逻辑说明总结引言在日常办公场景中,我们经常需要从 W

使用Spring Cache本地缓存示例代码

《使用SpringCache本地缓存示例代码》缓存是提高应用程序性能的重要手段,通过将频繁访问的数据存储在内存中,可以减少数据库访问次数,从而加速数据读取,:本文主要介绍使用SpringCac... 目录一、Spring Cache简介核心特点:二、基础配置1. 添加依赖2. 启用缓存3. 缓存配置方案方案

MySQL的配置文件详解及实例代码

《MySQL的配置文件详解及实例代码》MySQL的配置文件是服务器运行的重要组成部分,用于设置服务器操作的各种参数,下面:本文主要介绍MySQL配置文件的相关资料,文中通过代码介绍的非常详细,需要... 目录前言一、配置文件结构1.[mysqld]2.[client]3.[mysql]4.[mysqldum

使用Python实现无损放大图片功能

《使用Python实现无损放大图片功能》本文介绍了如何使用Python的Pillow库进行无损图片放大,区分了JPEG和PNG格式在放大过程中的特点,并给出了示例代码,JPEG格式可能受压缩影响,需先... 目录一、什么是无损放大?二、实现方法步骤1:读取图片步骤2:无损放大图片步骤3:保存图片三、示php

Python多线程实现大文件快速下载的代码实现

《Python多线程实现大文件快速下载的代码实现》在互联网时代,文件下载是日常操作之一,尤其是大文件,然而,网络条件不稳定或带宽有限时,下载速度会变得很慢,本文将介绍如何使用Python实现多线程下载... 目录引言一、多线程下载原理二、python实现多线程下载代码说明:三、实战案例四、注意事项五、总结引