医学软件项目开发(四):c++调用分割算法实例

一、配置问题

1.python36.lib

将pragma comment(lib,“python38_d.lib”)改为pragma comment(lib,“python38.lib”),并且注释掉 # define Py_DEBU

也可复制粘贴重命名python36_d.lib

2.修改object.h和pyconfig.h为引入import_array函数

//object.h54行修改
/* Py_DEBUG implies Py_TRACE_REFS. */
#if defined(Py_DEBUG) && !defined(Py_TRACE_REFS)
#define Py_TRACE_REFS
#endif

/* Py_DEBUG implies Py_TRACE_REFS. */
#if defined(Py_DEBUG) && !defined(Py_TRACE_REFS)
//#define Py_TRACE_REFS
#endif
//pyconfig358行修改
#if defined(Py_DEBUG) && !defined(Py_TRACE_REFS)
//#define Py_TRACE_REFS
#endif

#ifdef _DEBUG
//#	define Py_DEBUG
#endif
//代码前添加此函数
size_t init_numpy()
{//初始化 numpy 执行环境,主要是导入包,python2.7用void返回类型,python3.0以上用int返回类型
	import_array();
}

二、项目代码

//启动脊柱勾边分割
QVector<QPointF> BllSegPoint::spineOutline()
{

	QVector<QPointF> pathPointVector;
	//Py_SetPythonHome(L"C:/Program Files/Python36");
	Py_Initialize();
	// 检查初始化是否成功  
	if (!Py_IsInitialized())
	{
		qDebug() << "Py_IsInitialized Error";
		return pathPointVector;
	}
	
	if (m_num == 0)//临时-只运行一次
	{
		init_numpy();
		m_num++;
	}
	PyRun_SimpleString("import sys");
	PyRun_SimpleString("print ('---import sys---')");
	PyRun_SimpleString("sys.path.append('./')");
	PyRun_SimpleString("sys.path.append('D:/WorkSpace/MainModule1222/MainModule1222/x64/Debug/end2end_spine_outline/')");
	PyRun_SimpleString("sys.path.append('D:/anaconda3/envs/my_pytorch/Lib/site-packages')");

	
	PyObject *pModule = NULL;
	pModule = PyImport_ImportModule("end2end_spine");
	if (!pModule) {
		qDebug() << "BllSegPoint::segImageSpine(),Error,can't find end2end_spine.py";
		return pathPointVector;
	}

	PyObject *pFunc = NULL;
	pFunc = PyObject_GetAttrString(pModule, "main");

	Mat sml_img = DataFactory::S_OrgImg;
	//Mat sml_img = imread("1.jpg", 0);
	if (sml_img.size == 0)
	{
		qDebug() << "BllSegPoint::segImageSpine(),Error,没有图像数据。";
		return pathPointVector;
	}
	
	if (!sml_img.isContinuous())
	{
		sml_img = sml_img.clone();
	}
	npy_intp dims[] = { sml_img.rows, sml_img.cols };
	PyObject *pValue = PyArray_SimpleNewFromData(2, dims, NPY_UINT8, sml_img.data);

	//用tuple装起来传入python
	PyObject* pArgs = PyTuple_New(1);
	PyTuple_SetItem(pArgs, 0, pValue);
    
    
	//获取py返回值
	PyObject *pReturn = PyObject_CallObject(pFunc, pArgs);
	PyArrayObject* pRetArray = (PyArrayObject*)PyList_GetItem(pReturn, 0);//返回图像label
	PyArrayObject* pRetParams = (PyArrayObject*)PyList_GetItem(pReturn, 1);//返回路径的点值

	
	npy_intp *shape = PyArray_SHAPE(pRetArray);
	Mat big_img(shape[0], shape[1], CV_8UC1, PyArray_DATA(pRetArray));

	//返回的numpy矩阵的row和col
	int Rows = pRetParams->dimensions[0], columns = pRetParams->dimensions[1];

	for (int row = 0; row < Rows; row++)
	{
		int x = *((int *)PyArray_GETPTR2(pRetParams, row, 0));
		int y = *((int *)PyArray_GETPTR2(pRetParams, row, 1));
		QPoint p(x, y);
		pathPointVector.append(p);
	}
	Py_DECREF(pModule);
	Py_DECREF(pFunc);
	Py_DECREF(pArgs);
	Py_DECREF(pReturn);
	//Py_Finalize();
	return pathPointVector;
}
//脊柱区域分割算法
QVector<QVector<QPointF> > BllSegPoint::spineAreaSeg()
{
	QVector<QVector<QPointF> > pathPointVector(4);
	//Py_SetPythonHome((wchar_t*)"C:\Program Files\Python36");
	Py_Initialize();
	// 检查初始化是否成功  
	if (!Py_IsInitialized())
	{
		qDebug() << "Py_IsInitialized Error";
		return pathPointVector;
	}
	if (m_num == 0)//临时-只运行一次
	{
		init_numpy();
		m_num++;
	}
	PyRun_SimpleString("import sys");
	PyRun_SimpleString("import numpy as np");
	PyRun_SimpleString("print ('---import sys---')");
	PyRun_SimpleString("sys.path.append('./')");
	PyRun_SimpleString("sys.path.append('D:/WorkSpace/MainModule1222/MainModule1222/x64/Debug/end2end_spine_area/')");
	PyRun_SimpleString("sys.path.append('D:/anaconda3/envs/my_pytorch/Lib/site-packages')");

	PyObject *pModule = NULL;
	pModule = PyImport_ImportModule("end2end_spine_area");
	if (!pModule) {
		qDebug() << "BllSegPoint::spineAreaSeg(),Error,can't find end2end_spine_area.py";
		return pathPointVector;
	}

	PyObject *pFunc = NULL;
	pFunc = PyObject_GetAttrString(pModule, "amain");

	Mat sml_img = DataFactory::S_OrgImg;
	//Mat sml_img = imread("1.jpg", 0);

	if (sml_img.size == 0)
	{
		qDebug() << "BllSegPoint::segImageSpine(),Error,没有图像数据。";
		return pathPointVector;
	}

	if (!sml_img.isContinuous())
	{
		sml_img = sml_img.clone();
	}
	npy_intp dims[] = { sml_img.rows, sml_img.cols };
	PyObject *pValue = PyArray_SimpleNewFromData(2, dims, NPY_UINT8, sml_img.data);

	//用tuple装起来传入python
	PyObject* pArgs = PyTuple_New(1);
	PyTuple_SetItem(pArgs, 0, pValue);


	PyObject *pReturn = PyObject_CallObject(pFunc, pArgs);
	PyArrayObject* pRetParamsL1 = (PyArrayObject*)PyList_GetItem(pReturn, 0);//L1
	PyArrayObject* pRetParamsL2 = (PyArrayObject*)PyList_GetItem(pReturn, 1);//L2
	PyArrayObject* pRetParamsL3 = (PyArrayObject*)PyList_GetItem(pReturn, 2);//L3
	PyArrayObject* pRetParamsL4 = (PyArrayObject*)PyList_GetItem(pReturn, 3);//L4

	//获取py返回值
	npy_intp *shape = PyArray_SHAPE(pRetParamsL1);
	Mat big_img(shape[0], shape[1], CV_8UC1, PyArray_DATA(pRetParamsL1));

	//返回的numpy矩阵的row和col
	int Rows = pRetParamsL1->dimensions[0], columns = pRetParamsL1->dimensions[1];
	//返回的numpy矩阵的row和col

	for (int row = 0; row < Rows; row++)
	{
		int x1 = *((int *)PyArray_GETPTR2(pRetParamsL1, row, 0));
		int x2 = *((int *)PyArray_GETPTR2(pRetParamsL2, row, 0));
		int x3 = *((int *)PyArray_GETPTR2(pRetParamsL3, row, 0));
		int x4 = *((int *)PyArray_GETPTR2(pRetParamsL4, row, 0));
		int y1 = *((int *)PyArray_GETPTR2(pRetParamsL1, row, 1));
		int y2 = *((int *)PyArray_GETPTR2(pRetParamsL2, row, 1));
		int y3 = *((int *)PyArray_GETPTR2(pRetParamsL3, row, 1));
		int y4 = *((int *)PyArray_GETPTR2(pRetParamsL4, row, 1));
		QPointF p1(x1, y1);
		QPointF p2(x2, y2);
		QPointF p3(x3, y3);
		QPointF p4(x4, y4);
		pathPointVector[0].append(p1);
		pathPointVector[1].append(p2);
		pathPointVector[2].append(p3);
		pathPointVector[3].append(p4);
	}
	Py_DECREF(pModule);
	Py_DECREF(pFunc);
	Py_DECREF(pArgs);
	Py_DECREF(pReturn);
	//Py_Finalize();
	return pathPointVector;
}

三、注意事项

3.1Py_Finalize()

连续使用Py_Finalize(),程序会报错,故将其注释掉

3.2使用多个算法出错

python文件名和函数名问题,当调用多个算法时,如若是同样名字,算法执行过程的顺序不会如预期那样,会走串。这要求python中每个文件和对应的函数的命名都应当独一无二

你可能感兴趣的:(医学软件开发,c++,算法,python)