一. 背景
- 用pyhton可直接调用C++,减少重写的工作量;
- 部分逻辑运算,C++的执行效率高,可进行加速。
下面就一个简单的C++滤镜(彩色图转灰度图)为例,展示python调用C++
二. 代码实现
代码结构如下:
bash
.
├── build
├── CMakeLists.txt
├── image_processing.cpp # C++头文件
├── image_processing.h # C++源文件
└── image_process.py # python调用C++
各个文件的内容如下
image_processing.h
cpp
#ifndef IMAGE_PROCESSING_H
#define IMAGE_PROCESSING_H
#include <opencv2/opencv.hpp>
extern "C" {
void process_image(const unsigned char* input, unsigned char* output, int width, int height, int channels);
}
#endif // IMAGE_PROCESSING_H
image_processing.cpp
cpp
#include "image_processing.h"
void process_image(const unsigned char* input, unsigned char* output, int width, int height, int channels) {
cv::Mat input_image(height, width, channels == 3 ? CV_8UC3 : CV_8UC1, (void*)input);
cv::Mat output_image(height, width, CV_8UC1);
// 转换为灰度图像
cv::cvtColor(input_image, output_image, cv::COLOR_BGR2GRAY);
// 将处理后的图像数据复制到输出缓冲区
std::memcpy(output, output_image.data, width * height * sizeof(unsigned char));
}
image_process.py
python
import ctypes
import numpy as np
import cv2
import os
# 确定库文件路径
libname = "./build/libimage_processing.so"
# 加载共享库
image_lib = ctypes.CDLL(libname)
# 定义处理函数的原型
image_lib.process_image.argtypes = [
ctypes.POINTER(ctypes.c_ubyte), # 输入图像数据
ctypes.POINTER(ctypes.c_ubyte), # 输出图像数据
ctypes.c_int, # 宽度
ctypes.c_int, # 高度
ctypes.c_int # 通道数
]
# 读取图像
input_image = cv2.imread('input.jpg')
height, width, channels = input_image.shape
# 创建输出缓冲区
output_image = np.zeros((height, width), dtype=np.uint8)
# 调用 C++ 处理函数
input_ptr = input_image.ctypes.data_as(ctypes.POINTER(ctypes.c_ubyte))
output_ptr = output_image.ctypes.data_as(ctypes.POINTER(ctypes.c_ubyte))
image_lib.process_image(input_ptr, output_ptr, width, height, channels)
cv2.imwrite("output.jpg", output_image)
CMakeLists.txt
python
cmake_minimum_required(VERSION 3.10)
project(ImageProcessingLibrary)
# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
# 查找 OpenCV 库
find_package(OpenCV REQUIRED)
# 包含 OpenCV 头文件
include_directories(${OpenCV_INCLUDE_DIRS})
# 添加库
add_library(image_processing SHARED image_processing.cpp)
# 链接 OpenCV 库
target_link_libraries(image_processing ${OpenCV_LIBS})
三. 编译代码 && 调用动态库
1. 编译代码
bash
# 执行下面命令后,会生成动态库,./build/libimage_processing.so
mkdir build
cd build
cmake ..
make
2. 调用动态库
bash
python image_process.py
效果如下(模拟灰度滤镜):