需求:c++ 将图片写入共享内存,python读取。将c++写的共享内存的操作封装为一个so库,c++ 和python共同调用这个库,便于双方的操作,省去信号量的管理操作。
一,c++写入端
int main(int argc, char **argv)
{
SharedMemoryOption op;
op.id = 2017;
op.size = 1048576 * 40;
op.mode = work_mode::WRITE;
SharedMemory::Ptr shm = std::make_shared<SharedMemory>(op);
cv::Mat rawImg = cv::imread("2.jpg");
if(rawImg.empty()){
return 0;
}
while (1)
{
shm->writeImg(reinterpret_cast<char *>(rawImg.data),rawImg.cols,rawImg.rows,rawImg.channels());
std::this_thread::sleep_for(std::chrono::milliseconds(200));
}
return 0;
}
二,python读取端
#coding=utf-8
from ctypes import *
import sys
import numpy as np
import cv2
import math
import time
if __name__ =='__main__':
print(cv2.__version__)
dll = CDLL("../../build/libShm.so")
#初始化
dll.init(2017,1048576 * 40,0)
width = c_int()
height = c_int()
channels = c_int()
dll.readImg.restype = POINTER(c_char)
while True:
tick = time.time()
data=dll.readImg(byref(width),byref(height),byref(channels))
size =width.value*height.value*channels.value
#获取内存中,指定地址、指定长度的字节
image_data = string_at(data, size)
#返回的是一个数组,这个数组的内容是缓冲区的内容
image_array = np.frombuffer(image_data, dtype=np.uint8)
img = image_array.reshape((height.value,width.value,channels.value))
tock = time.time()
print(f"取图耗时为: {(tock - tick)*1000:.2f}ms")
cv2.imwrite('output.jpg', img)
三,测试结果
nx平台,4M的图,读取时间大约在20ms 左右。第一次很慢。
四,优化点
写入端将图片宽,高,通道数 写道共享内存的前三个int,这样读取的时候先读取三个int,之后根据前三个int读取具体图片内容。