【机器学习】C++与OpenCV、Tensorflow-python联合调用

  上一篇我介绍了C++调用Python的入门方法。这一篇我讲述C++与OpenCV、Tensorflow-python联合调用的一次成功的实验过程。
  C++通过python调用tensorflow,比调用C++版本的tensorflow的优势在于:tensorflow环境依赖python环境,python环境几乎是一键傻瓜式操作,各种库依赖的问题,比直接使用tensorflow-C++少得多,只要python配置好了,C++项目根本不需要单独配置tensorflow,完全靠python模块。在C++项目配置中,根本不需要添加tensorflow的include头文件目录和库目录。
  OpenCV是一个通用的计算机视觉库,C++版本几乎是傻瓜式编译,最后只输出opencv_world310d.lib / opencv_world310.lib库文件,和 opencv_world310d.dll / opencv_world310.dll动态链接库,头文件只需要包含#include <opencv2/opencv.hpp>,可以说OpenCV-C++配置相当简单。
  在C++项目中配置好python,numpy和OpenCV之后,就可以开始写测试代码了:

#include <opencv2/opencv.hpp>
#include <iostream>
#include <Python.h>  
#include <numpy/arrayobject.h>
#include <string>  
using std::cin;
using std::cout;
using std::endl;
using std::string;
int main(int argc, char *argv[])
{
    Py_InitializeEx(1); //初始化 python  
    import_array();
    if (!Py_IsInitialized())
    {
        cout << "initialized error" << endl;
        return -1;
    }
    PyObject* sys = PyImport_ImportModule("sys");
    std::cout << std::string(Py_GetVersion()) << "\n";
    PyRun_SimpleString("import  sys"); // 执行 python 中的短语句  
    PyRun_SimpleString("print('come in python')");
    PyRun_SimpleString("sys.path.append('./')");
    PyObject  *pModule(0), *pDct(0);
    pModule = PyImport_ImportModule("tfTest");
    if (!pModule)
    {
        PyErr_Print();
        cout << "can not find pytest.py" << endl;
        return -1;
    }
    else
        cout << "open Module" << endl;
    cv::Mat oimg = cv::imread("camera.jpg", cv::IMREAD_UNCHANGED);
    cv::Mat img;
    cv::cvtColor(oimg, img, cv::COLOR_BGR2GRAY);//测试灰度图
    auto sz = img.size();
    int x = sz.width;
    int y = sz.height;
    int z = img.channels();
    int xy = x*y;
    int channel = img.channels();
    uchar *CArrays = new uchar[x*y*z];
    int iChannels = img.channels();
    int iRows = img.rows;
    int iCols = img.cols * iChannels;
    if (img.isContinuous())
    {
        iCols *= iRows;
        iRows = 1;
    }
    uchar* p;
    int id = -1;
    for (int i = 0; i < iRows; i++)
    {
        // get the pointer to the ith row
        p = img.ptr<uchar>(i);
        // operates on each pixel
        for (int j = 0; j < iCols; j++)
        {
            CArrays[++id] = p[j];//连续空间
        }
    }
    npy_intp Dims[3] = { y, x, z}; //注意这个维度数据!
    PyObject *pDict = PyModule_GetDict(pModule);

    PyObject *PyArray = PyArray_SimpleNewFromData(3, Dims, NPY_UBYTE, CArrays); 
    PyObject *PyPath = Py_BuildValue("s", "conv.jpg");
    PyObject *ArgArray = PyTuple_New(2);
    PyTuple_SetItem(ArgArray, 1, PyArray); //同样定义大小与Python函数参数个数一致的PyTuple对象
    PyTuple_SetItem(ArgArray, 0, PyPath); //同样定义大小与Python函数参数个数一致的PyTuple对象
    PyObject *pFunc = PyDict_GetItemString(pDict, "CVSaveImage");
    PyObject_CallObject(pFunc, ArgArray);//调用函数,传入Numpy Array 对象。
    PyErr_Print();
    Py_DECREF(ArgArray);
    Py_DECREF(pDict);
    Py_DECREF(sys);
    Py_DECREF(pModule);
    Py_Finalize();
    delete[] CArrays;
    return 0;
}

  OpenCV读取的图像是一个连续空间,可以直接赋值给numpy数组。如果是彩色图像,那么OpenCV Mat数据格式为一个[3*W,H]的一维数组,其中每一行数据是按照R,G,B,R,G,B。。。来保存,和OpenCV-python读取图像后得到的numpy数组格式是一致的,因此彩色图像也可以使用上述代码转换为numpy数据。
  python代码为:

#coding:utf-8
import tensorflow as tf
import numpy as np
import cv2
def CVSaveImage(path, img1):
    img = img1.reshape([img1.shape[0],img1.shape[1],1,1])
    img = img.transpose(3,0,1,2)
    dia = 5
    kernel = np.ones((dia,dia))/(dia**2.)
    kernel = kernel.reshape([dia,dia,1,1])
    sess = tf.Session()
    A=tf.placeholder("float", shape=[1,img1.shape[0],img1.shape[1],1])
    B=tf.placeholder("float", shape=[dia,dia,1,1])
    initial = tf.random_normal([1,img1.shape[0],img1.shape[1],1]) * 0.256
    X = tf.Variable(initial)
    init = tf.global_variables_initializer()
    sess.run(init)
    X = tf.nn.conv2d(A,B,strides=[1,1,1,1],padding='SAME')
    img2 = sess.run(X,feed_dict={A: img, B:kernel})
    print(img2.shape)
    img2= img2.transpose([1,2,3,0])
    img2= img2.reshape([img1.shape[0],img1.shape[1]])
    cv2.imwrite(path,img2) 

  这里我默认使用了灰度图来进行处理,channel通道始终是1。这个代码的功能是把图像进行一次均值滤波,得到结果:
  这里写图片描述
  这里写图片描述
  这里写图片描述
  至此,C++与OpenCV、Tensorflow-python联合调用完成。
  图像黑边是我截图的问题,原图是没有的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值