python和C++共享内存传输图像的示例
作者:小蜗牛叽咕往前 发布时间:2021-03-28 01:27:57
标签:python,c++,共享内存,传输图像
原理
python没有办法直接和c++共享内存交互,需要间接调用c++打包好的库来实现
流程
C++共享内存打包成库
python调用C++库往共享内存存图像数据
C++测试代码从共享内存读取图像数据
实现
1.c++打包库
创建文件
example.cpp
#include <iostream>
#include <cassert>
#include <stdlib.h>
#include <sys/shm.h>
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/videoio.hpp"
#define key 650
#define image_size_max 1920*1080*3
using namespace std;
using namespace cv;
typedef struct{
int rows;
int cols;
uchar dataPointer[image_size_max];
}image_head;
int dump(int cam_num,int row_image, int col_image, void* block_data_image)
{
int shm_id = shmget(key+cam_num,sizeof(image_head),IPC_CREAT);
if(shm_id == -1)
{
cout<<"shmget error"<<endl;
return -1;
}
cout << " shem id is "<<shm_id<<endl;
image_head *buffer_head;
buffer_head = (image_head*) shmat(shm_id, NULL, 0);
if((long)buffer_head == -1)
{
cout<<"Share memary can't get pointer"<<endl;
return -1;
}
assert(row_image*col_image*3<=image_size_max);
image_head image_dumper;
image_dumper.rows=row_image;
image_dumper.cols=col_image;
uchar* ptr_tmp_image=(uchar*) block_data_image;
for (int i=0;i<row_image*col_image*3;i++)
{
image_dumper.dataPointer[i] = *ptr_tmp_image;
ptr_tmp_image++;
}
memcpy(buffer_head,&image_dumper,sizeof(image_dumper));
return 1;
}
extern "C"
{
int dump_(int cam_num,int row_image, int col_image, void* block_data_image)
{
int result=dump(cam_num,row_image, col_image, block_data_image);
return result;
}
}
CMakeLists.txt
# cmake needs this line
cmake_minimum_required(VERSION 2.8)
# Define project name
project(opencv_example_project)
# Find OpenCV, you may need to set OpenCV_DIR variable
# to the absolute path to the directory containing OpenCVConfig.cmake file
# via the command line or GUI
find_package(OpenCV REQUIRED)
# If the package has been found, several variables will
# be set, you can find the full list with descriptions
# in the OpenCVConfig.cmake file.
# Print some message showing some of them
message(STATUS "OpenCV library status:")
message(STATUS " version: ${OpenCV_VERSION}")
message(STATUS " libraries: ${OpenCV_LIBS}")
message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}")
if(CMAKE_VERSION VERSION_LESS "2.8.11")
# Add OpenCV headers location to your include paths
include_directories(${OpenCV_INCLUDE_DIRS})
endif()
# Declare the executable target built from your sources
add_library(opencv_example SHARED example.cpp)
add_executable(test_example test_run.cpp)
# Link your application with OpenCV libraries
target_link_libraries(opencv_example ${OpenCV_LIBS})
target_link_libraries(test_example ${OpenCV_LIBS})
最后生成库
2.python调用C++动态库进行存图
#!/usr/bin/env python
import sys
#sys.path.append("/usr/lib/python3/dist-packages")
#sys.path.append("/home/frank/Documents/215/code/parrot-groundsdk/.python/py3/lib/python3.5/site-packages")
import cv2
import ctypes
import numpy as np
ll = ctypes.cdll.LoadLibrary
lib = ll("./build/libopencv_example.so")
lib.dump_.restype = ctypes.c_int
count = 1
#path = "/home/frank/Documents/215/2020.10.24/python_ctypes/image/"
while count < 30:
path = "./image/"+str(count)+".jpg"
print(path)
image=cv2.imread(path)
#cv2.imshow("test",image)
#cv2.waitKey(0)
image_data = np.asarray(image, dtype=np.uint8)
image_data = image_data.ctypes.data_as(ctypes.c_void_p)
value = lib.dump_(0,image.shape[0], image.shape[1], image_data)
print(value)
count += 1
if count == 30:
count = 1
3.C++读取共享内存获取图像
#include <iostream>
#include <stdlib.h>
#include <sys/shm.h>
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/videoio.hpp"
#define key 650
#define image_size_max 1920*1080*3
using namespace cv;
using namespace std;
typedef struct{
int rows;
int cols;
uchar dataPointer[image_size_max];
}image_head;
int main()
{
int count = 1;
while(true)
{
int shm_id = shmget(key+0,sizeof(image_head) ,IPC_CREAT);
if(shm_id == -1)
{
cout<<"shmget error"<<endl;
return -1;
}
cout << " shem id is "<<shm_id<<endl;
image_head* buffer_head;
buffer_head = (image_head*)shmat(shm_id, NULL, 0);
if((long)buffer_head == -1)
{
perror("Share memary can't get pointer\n");
return -1;
}
image_head image_dumper;
memcpy(&image_dumper, buffer_head, sizeof(image_head));
cout<<image_dumper.rows<<" "<<image_dumper.cols<<endl;
uchar* data_raw_image=image_dumper.dataPointer;
cv::Mat image(image_dumper.rows, image_dumper.cols, CV_8UC3);
uchar* pxvec =image.ptr<uchar>(0);
int count = 0;
for (int row = 0; row < image_dumper.rows; row++)
{
pxvec = image.ptr<uchar>(row);
for(int col = 0; col < image_dumper.cols; col++)
{
for(int c = 0; c < 3; c++)
{
pxvec[col*3+c] = data_raw_image[count];
count++;
}
}
}
cv::imshow("Win",image);
cv::waitKey(1);
}
return 1;
}
来源:https://www.cnblogs.com/kekeoutlook/p/13871052.html


猜你喜欢
- 背景说起Mysql死锁,之前写过一次有关Mysql加锁的基本介绍,对于一些基本的Mysql锁或者死锁都有一个简单的认识,可以看下这篇文章为什
- 就算我们每天在叫嚷着创新经济,设计救国,我们在生活中也无处不在的看到各种设计庸俗、制作粗劣的海报、店面、户外广告、大胸美女和肌肉 * 交相辉映
- 现在是好时机来指出Django和URL配置背后的哲学: 松耦合 原则。 简单的说,松耦合是一个 重要的保证互换性的软件开发方法。Django
- # 源码如下:#!/usr/bin/env python#coding=utf-8import osfrom PIL import Imag
- 在使用Tensorflow的过程中,我们经常遇到数组形状不同的情况,但有时候发现二者还能进行加减乘除的运算,在这背后,其实是Tensorfl
- 1.乘法和幂运算符● 单个 * 用于乘法运算● 两个 ** 表示幂运算>>> 2*3>>> 6>&
- 前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿遍又亿遍,久久不能离开!看着仙紫小姐姐的蹦迪视频,除了一键三连还能做什么?突发奇想
- 看到这个标题,你我可能都笑了。你会笑,因为你以为这个东西太小儿科了,还用得着做一个标题?!我会笑,是因为我确信你看完后会改变你的想法。首先我
- 本文实例讲述了symfony2.4的twig中date用法。分享给大家供大家参考,具体如下:获得当前时间:{{ "now"
- SQL Server中一共提供了三个字符串截取函数:LEFT()、RIGHT()、SUBSTRING()。一、LEFT()函数函数说明如下:
- 本文实例讲述了PHP共享内存使用与信号控制。分享给大家供大家参考,具体如下:共享内存共享内存的使用主要是为了能够在同一台机器不同的进程中共享
- 本文介绍了C#连接Oracle数据库的过程。通过instant client和ODP.net中的Oracle.DataAccess.dll,
- 1.GO中包的定义与介绍go中包分为三种:1.系统内置包 2. 自定义包 3.第三方包2. 包管理工具 go mod2.1 自定义包 (可以
- 引入我们在使用mysql数据库时,习惯使用int型作为主键,并设置为自增,这既能够保证唯一,使用起来又很方便,但int型的长度是有限的,如果
- 一、问题引出浅拷贝首先看下面代码的执行情况:a = [1, 2, 3]print('a = %s' % a) # a = [
- 新手小白,一直在为cmd窗口的暗白色文字感到苦恼,在网上找了许多方法(也就那两种吐舌头),现在稍微整理了一下,便于使用。效果图:import
- 目前可实现:MD5算法、SHA256算法、先MD5后SHA256、先SHA256后MD5、两次MD5、两次SHA256、前8位MD5算法后8
- 前言几乎每个程序都需要用到图片。下面就来给大家介绍前端+PHP后端实现微信小程序实现图片上传功能,分享出来供大家参考学习,下面话不多说了,来
- 1.之前的写法(不报错):data = cursor.fetchall()data_name = data[0]['task_typ
- 使用pip安装python库的几种方式1、使用pip在线安装1.1 安装单个package格式如下:pip install SomePack