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;
}

以上就是python和C++共享内存传输图像的示例的详细内容,更多关于python和c++传输图像的资料请关注我们其它相关文章!

(0)

相关推荐

  • python或C++读取指定文件夹下的所有图片

    本文实例为大家分享了python或C++读取指定文件夹下的所有图片,供大家参考,具体内容如下 1.python读取指定文件夹下的所有图片路径和图片文件名 import cv2 from os import walk,path def get_fileNames(rootdir): data=[] prefix = [] for root, dirs, files in walk(rootdir, topdown=True): for name in files: pre, ending = pa

  • 使用C++调用Python代码的方法详解

    一.配置python环境问题 1.首先安装Python(版本无所谓),安装的时候选的添加python路径到环境变量中 安装之后的文件夹如下所示: 2.在VS中配置环境和库 右击项目->属性->VC++目录 1)包含目录: Python安装路径/include 2)库目录: Python安装路径/libs 右击项目->属性->连接器->输入->附加依赖库 debug下: python安装目录/libs/python37_d.lib release下: python安装目录

  • Python3安装模块报错Microsoft Visual C++ 14.0 is required的解决方法

    问题一:安装模块时出现报错 Microsoft Visual C++ 14.0 is required,也下载安装了运行库依然还是这个错误 解决: 1.打开Unofficial Windows Binaries for Python Extension Packages(http://www.lfd.uci.edu/~gohlke/pythonlibs/),这里面有很多封装好的Python模块的运行环境 2.找到所需要下载的模块文件对应版本进行下载. 如,需要下载Pymssql,本机安装是32位

  • Windows系统Python直接调用C++ DLL的方法

    环境:Window 10,VS 2019, Python 2.7.12, 64bit 1,打开 VS 2019,新建C++ Windows 动态链接库工程 Example,加入下列文件,如果Python是64位的则在VS中 Solution platforms 选择 x64 编译成64位的 DLL: Example.h #pragma once #ifndef CPP_EXPORTS #define CPP_EXPORTS #endif #ifdef CPP_EXPORTS #define CP

  • pybind11: C++ 工程提供 Python 接口的实例代码

    C/C++ 工程提供 Python 接口,有利于融合进 Python 的生态.现在 Python 在应用层,有其得天独厚的优势.尤其因为人工智能和大数据的推波助澜, Python 现在以及未来,将长期是最流行的语言之一. 那 C/C++ 怎么提供 Python 接口呢? ctypes: C 与 Python 绑定, Python 内建模块 Boost.Python: C++ 与 Python 绑定, Boost 模块 pybind11: C++11 与 Python 绑定, 减去了旧 C++ 支

  • Python嵌入C/C++进行开发详解

    如果你想把Python嵌入C/C++中是比较简单的事情,你需要的是在VC中添加Python的include文件目录和lib文件目录.下面我们来看下如何把Python嵌入C/C++中. VC6.0下,打开 tools->options->directories->show directories for,将Python安装目录下的inlude目录添加到inlude files项中,将libs目录添加到library files项中. VC2005下,打开tools->options-

  • 基于Python和C++实现删除链表的节点

    给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点. 返回删除后的链表的头节点. 示例 1: 输入: head = [4,5,1,9], val = 5 输出: [4,1,9] 解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9. 示例 2: 输入: head = [4,5,1,9], val = 1 输出: [4,5,9] 解释: 给定你链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 ->

  • 使用C++调用Python代码的方法步骤

    一.配置python环境问题 1.首先安装Python(版本无所谓),安装的时候选的添加python路径到环境变量中 安装之后的文件夹如下所示: 2.在VS中配置环境和库 右击项目->属性->VC++目录 1)包含目录: Python安装路径/include 2)库目录: Python安装路径/libs 右击项目->属性->连接器->输入->附加依赖库 debug下: python安装目录/libs/python37_d.lib release下: python安装目录

  • C、C++、Java到Python,编程入门学习什么语言比较好

    摘要:回顾编程语言几十年来的兴衰起伏,似乎也折射了整个信息产业的变迁消亡,想要在技术的洪流里激流勇进,找准并学精一两门编程语言更加显得至关重要. 最近,TIOBE更新了7月的编程语言榜单,常年霸榜的C.Java和Python依然蝉联前三位.万万没想到的是,R语言居然冲到了第八位,创下了史上最佳记录.而且后续随着业内对数据统计和挖掘需求的上涨,R语言热度颇有些势不可挡的架势. 然而作为程序员吃饭的工具,编程语言之间也形成了某种鄙视链,各大论坛里弥漫着剑拔弩张的气氛,众口难调.也难怪有很多初学者会有

  • Python扩展C/C++库的方法(C转换为Python)

    参考网址:https://www.shanlily.cn/archives/330 一.简介 Python是个非常流行的解释型脚本语言.而C是一个非常流行的编译语言.由于其编译的性质,导致C一般比Python要快,但是它是更底层的.相对的,Python编程更加快速和简单.故而将C库作为Python库的扩展极为必要,使得Python既融合了自身的优点,又融合了C语言的优点,正是因为这些性质使得Python越来越流行. 二.通过swing扩展C库 (1) 安装swig 命令: sudo apt-ge

  • ubunt18.04LTS+vscode+anaconda3下的python+C++调试方法

    1.安装背景 最近想放弃windows编程环境,转到linux.原因就一个字:潮 从格式化所有硬盘,到安装win10/ubuntu18.04双系统,其中的痛苦,我想只有经历过的人才会知道. 在这里,我还是提一些安装双系统的几点建议吧: ① 先装win10,我是使用老毛桃在线安装的专业版 ② 装ubuntu很烦人,本以为通过教程(先下载iso,再制作启动u盘,再修改bios中的u盘优先启动方式)就可以了,最终无果.我只好用实验室同学已经制作好的ubuntu 启动盘进行安装,结果开启出现了gnru,

随机推荐