c++调用python,传入多个mat图像

以下是c++调用python,c++块代码:
实现:
1、对python的调用
2、传入mat图像矩阵,解析为python对象,再使用python代码进行检测,返回结果
3、对结果进行解析,添加相应处理

#include<D:\software\python\py37\include\Python.h>
#include<opencv.hpp>
#include<dnn.hpp>
#include<arrayobject.h>
#include<imgproc.hpp>
#include<highgui.hpp>
#include<fstream>
#include<sstream>
#include<vector>
#include<filesystem>
#include<io.h>
#include<iostream>
#include<string.h>
using namespace std;
// 
void get_need_file(string path,vector<string>&file,string ext);

int main()
{
	Py_SetPythonHome((wchar_t*)L"D:\\software\\python\\py37\\");  //设置所使用python环境的路径
	Py_Initialize(); //完成Python解释器的初始化
	PyRun_SimpleString("import sys");   //导入库,用于添加路径信息
	PyRun_SimpleString("import cv2");   // 导入库(python代码里导入的一致)
	PyRun_SimpleString("import numpy as np");
	PyRun_SimpleString("import os");
	PyRun_SimpleString("import torch");
	PyRun_SimpleString("import onnxruntime");
	PyRun_SimpleString("import torchvision");
	PyRun_SimpleString("import time");
	PyRun_SimpleString("import os");
	PyRun_SimpleString("import random");
	//PyRun_SimpleString("sys.path.append(r'D:\\pycharm_project')");//
	PyRun_SimpleString("sys.path.append(r'./')");//当前路径添加到Python sys路径
	clock start,finish;  //时间函数
	start=clock();
	import_array();
	//设置一些Python解释器中的对象
	PyObject* pModule = NULL; 
	PyObject* pFunc = NULL;  
	PyObject* pParams = NULL; 
	PyObject* pResult = NULL;  
	
	//pModule = PyImport_ImportModule("yolo5");  
	pModule = PyImport_Import(PyUnicode_FromString("yolo5"));
	if (pModule == NULL)
	{
		cout << "don't find the python file!" << endl;
	}
	pFunc = PyObject_GetAttrString(pModule, "run"); 
	
	// 单张图像,或者一个图像文件夹路径
	//pParams = Py_BuildValue("(s)", "D:/pycharm_project/yolov5-6.1/data/images/bus.jpg");
	//pParams = Py_BuildValue("(ii)", 1, 1); 
	
	// 用于测试:处理12张图像为mat,并写入vector
	vector<Mat> mats;
	string source = "d:\\xxx\\xxx" ; //图片路径
	vector<string> my_file;
	string need_extension=".PNG";
	get_need_file(source,my_file,need_extension);
	for (size_t i=0;i<my_file.size(),i++)
		{
		Mat src=cv::imread(my_file[i],1);
		mats.push_back(src);
		}
	
	// 把12张mat图像 转为python对象,传给python进行处理
	PyObject* listargs=PyTuple_New(12);
	for (int  j=0;j<12;j++)
	{
		cv::Mat mat=mats[j];
		npy_intp dims[3]={mat.rows,mat.cols,mat.channels()};
		PyObject* PyArray=(PyObject*)PyArray_SimpleNewFromData(3,dims,NPY_UBYTE,(unsigned char *)mat.data);
		PyTuple_SetItem(listargs,j,PyArray);
	}
	PyObject* arglist=PyTuple_New(1);	
	PyTuple_SetItem(arglist,0,listargs);
	
	//只是处理一张图像
	/*
	PyObject* arglist=PyTuple_New(1);
	npy_intp dims[3]={img.rows,img.cols,img.channels()};
	PyObject* PyArray=(PyObject*)PyArray_SimpleNewFromData(3,dims,NPY_UBYTE,(unsigned char *)img.data);
	PyTuple_SetItem(arglist,0,PyArray);
	*/

	//调用函数,返回处理结果
	pResult = PyObject_CallObject(pFunc, arglist);
	// 由于调试,判断python文件在调用运行是否有错
	if (PyErr_Occurred) {
		PyErr_Print();
		PyErr_Clear();
	}
	if(pResult==NULL){
		cout<<"res is null"<<endl;
	}
	Py_DECREF(arglist);
	Py_DECREF(pFunc);
    // 创建一些变量
    int x,y,count=0;
    string *dirpath=nullptr;
    vector<Point> &Vpoint;
    //map<int, vector<Point>*pMapcoordinate>;
    if(PyList_Check(pResult)){
		int sizeofarray=PyList_Size(pResult)-1;
		PyObject* ne=PyList_GetItem(pResult,sizeofarray); // 图像渲染的地址
		for(int i=0;i<sizeofarray;i++){
		count+=1;
		PyObject* next=PyList_GetItem(pResult,i);
		PyArg_ParseTuple(next,"i|i",&x,&y);
		Point coordinate(x,y);
		Vpoint.push_back(coordinate);
		//pMapcoordinate->insert(make_pair(1,Vpoint));
	}
	PyArg_ParseTuple(ne,"s",&dirpath); //解析:图像渲染地址写到list,和中心点在一起
}
	for(vector<Point>::iterator iter=Vpoint.begin();iter!=Vpoint.end();++iter){
		cout<<*iter<<endl;
	}
	finish=clock();
	Py_Finalize(); //释放所有Python申请的资源
	count<<"all time:"<<finish-start<<endl;
}

// 遍历文件夹所有图像
void get_need_file(string path,vector<string>&file,string ext){
	intptr_t file_handle=0;
	struct _finddata_t file_info;
	string temp;
	if((file_handle=_findfirst(temp.assign(path).append("/*"+ext).c_str(),&file_info))!=-1){
		do{
		file.push_back(temp.assign(path).append("/").append(file_info.name);
		}while(_findnext(file_handle,&file_info)==0);
		_findclose(file_handle);
	}
}

python端代码:
1、使用多线程并行处理图像

inport concurrent
def run(source):
	mode=YOLOV5("xx.onnx)
	count_all=0 #检测数目
	coor=[]  #中心坐标点
	img_files=[os.path.join(source,file) for file in os.listdir(source)]
	# 启动12个线程,如果读取命名是数字的图片,可能导致无序。字母命名的正常
	# 使用for循环,指定数据路径,图片每次检测都是不变的,但是速度会慢
	with concurrent.futures.ThreadPoolExecutor(max_workers=12) as executor: 
		furures=[executor.submit(model.inference,imgpath) for imgpath in img_files]
		concurrent.futures.wait(futures)
		for future in concurrent.futures.as_completed(futures):
			outboox=fliter_box(future.result()[0],0.1,0.2)
			res,count=draw(future.result()[1],outboox)
			count_all+=count
			coor.append(res)
		executor.shutdown()
	return count_all,coor
run("d:/img_path")
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值