Python C++扩展

前段时间看了一篇文章,http://blog.jobbole.com/78859/, 颇有感触,于是就结合自己工作中的知识作了一个简单的Python移动侦测:移动侦测的算法使用C++实现,封装成Python可以调用的格式,具体流程如图1。

图1

首先看一下C++的工程配置,如图2

   

图2

C++部分代码:

#include "stdafx.h"
#include "Python.h"
#include "C:\Python27\Lib\site-packages\numpy\core\include\numpy\arrayobject.h"
#include "motiondetector.h"

static int MD_GRID_W      = 32;
static int MD_GRID_H      = 32;
static int MD_NOISE_LEVEL = 150;
static int MD_SENSITIVITY = 150;

class VideoDetector
{
public:
 ~VideoDetector()
 {
  if (m_motionDetector != NULL)
  {
   delete m_motionDetector;
   m_motionDetector = NULL;
   printf("~VideoDetector\r\n");
  }
 }
 VideoDetector(int width, int height):m_width(width), m_height(height)
 {
        m_motionDetector = new simple_md::MotionDetector();
  if (m_motionDetector != NULL)
  {
      m_motionDetector->init(MD_GRID_W, MD_GRID_H, m_width, height);
   m_motionDetector->set_noise_level(MD_NOISE_LEVEL);
   m_motionDetector->set_sensitivity(MD_SENSITIVITY);

// Setup default zone
   std::vector<simple_md::Zone> zones;
   simple_md::Zone z;
   z.sensitivity = 100;

for (int i = 0; i < MD_GRID_W * MD_GRID_H; ++i)
   {
    z.mask.push_back(100);
   }

zones.push_back(z);
   m_motionDetector->set_zones(zones);
   m_motionDetector->set_md_enbale();
         printf("VideoDetector\r\n");
  }
 }

int process_frame(uint8_t *frame)
 {
  
  if (m_motionDetector != NULL && frame != NULL)
  {

m_motionDetector->feed_frame(frame, m_width, m_height, m_width - 1, GetTickCount(), NULL, 0, NULL, 0, NULL, 0);
   return m_motionDetector->get_state();
  }
  return 0;
 }

int test(void)
 {
  return m_width * m_height;
 }
private:
 VideoDetector();
 simple_md::MotionDetector *m_motionDetector;
 int m_width;
 int m_height;
};

static void PyDelVideoDetector(void *ptr)
{
    printf("VideoDetector_UnInit\n");
 VideoDetector *tmp = static_cast<VideoDetector *>(ptr);
 delete tmp;
 return;
}

PyObject *VideoDetector_Init(PyObject *self, PyObject *args)
{
 printf("VideoDetector_Init\n");
 int arg1 = 0;
 int arg2 = 0;
 int ret = PyArg_ParseTuple(args, "ii", &arg1, &arg2);
 if (ret == 0)
 {
  printf("VideoDetector_Init fail\n");
  return NULL;
 }
 VideoDetector *vd = new VideoDetector(arg1, arg2);
 return PyCObject_FromVoidPtr(vd, PyDelVideoDetector);
}

#define f(x0) (*((uint8_t*)PyArray_DATA(py_pix) + (x0) * PyArray_STRIDES(py_pix)[0]))
#define shape(i) (py_pix->dimensions[(i)])

PyObject *VideoDetector_Process(PyObject *self, PyObject *args)
{
 printf("VideoDetector_Process\n");
 PyObject *py_obj = 0;
 PyArrayObject *py_pix = 0;
 npy_int64 idx = 0;
 int ret = PyArg_ParseTuple(args, "OO", &py_obj, &py_pix);
 if (ret == 0)
 {
     printf("VideoDetector_Process fail\n");
  return NULL;
 }

uint8_t *frame = (uint8_t *)malloc(sizeof(uint8_t) * shape(0));
 if (frame == NULL)
 {
  return NULL;
 }

for (idx = 0; idx < shape(0); idx++)
 {
  *(frame + idx) = (uint8_t)f(idx);
 }
    printf("-------process_frame start-------\n");
 void * tmp = PyCObject_AsVoidPtr(py_obj);
 VideoDetector *vd = static_cast<VideoDetector *>(tmp);
 int result = vd->process_frame(frame);
 free(frame);
 frame = NULL;
 printf("-------process_frame end(%d)-------\n", result);
 return Py_BuildValue("i", result);
}

PyObject *VideoDetector_Test(PyObject *self, PyObject *args)
{
 printf("VideoDetector_Test\n");
 PyObject *pynum = 0;
 int ret = PyArg_ParseTuple(args, "O", &pynum);
 if (ret == 0)
 {
     printf("VideoDetector_Test fail\n");
  return NULL;
 }
 void * tmp = PyCObject_AsVoidPtr(pynum);
 VideoDetector *vd = static_cast<VideoDetector *>(tmp);
 int result = vd->test();
 return Py_BuildValue("i", result);
}

static PyMethodDef VideoDetector_methods[] = {
 {"VideoDetector", VideoDetector_Init    , METH_VARARGS},
 {"test"    ,      VideoDetector_Test    , METH_VARARGS},
 {"process"    ,   VideoDetector_Process , METH_VARARGS},
 {NULL, NULL, 0}
};

PyMODINIT_FUNC initVideoDetector(void)
{
 Py_InitModule("VideoDetector", VideoDetector_methods);
}

videodetector.py代码:

from VideoDetector import *

class videodetector(object):
 def __init__(self, arg1, arg2):
  self._base = VideoDetector(arg1, arg2)
 def test(self):
  return test(self._base)
 def process(self, frame):
  return process(self._base, frame)

camera.py代码:

import cv2
import time
import datetime
import numpy as np
from videodetector import *

frame_num = 0

def motion_detect(obj, frame):
 global frame_num
 if frame_num % 5 == 0:
  print frame_num
  pixels = []
  for ch in frame.tostring():
   pixels.append(ord(ch))

#rgb2yuv = np.array([[0.299, 0.587, 0.114],
        #                    [-0.14713, -0.28886, 0.436],
        #                    [0.615, -0.51499, -0.10001]])
  #rgb = np.array(pixels).reshape(len(pixels) / 3, 3)
  #yuv = np.dot(rgb, rgb2yuv.T)
  #y = np.array(yuv[ :, 0]).reshape(len(yuv), 1)
  #print yuv.shape
  #print y.shape
  #print obj.process(y)
  
  rgb = np.array(pixels).reshape(len(pixels) / 3, 3)
  r = rgb[ : , 0];
  g = rgb[ : , 1];
  b = rgb[ : , 2];
  raw = r + g + b;
  #print datetime.datetime.now().second
  #print datetime.datetime.now().microsecond
  print raw.shape;
  print obj.process(raw)
 frame_num += 1

camera = cv2.VideoCapture(0)
fps = camera.get(cv2.cv.CV_CAP_PROP_FPS)
(width, height) = (int(camera.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH)), int(camera.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT)))
print width
print height
obj = videodetector(width, height)
#print obj.test()

print("program begin")
while True:
 (grabbed, frame) = camera.read()
 if not grabbed:
  continue
 cv2.imshow("Frame", frame)
 motion_detect(obj, frame)
 key = cv2.waitKey(1) & 0xFF
 if key == ord("q"):
  break
print("program end")
camera.release()
cv2.destroyAllWindows()
print("program release")

效果如图3:

图3

Python C++扩展的更多相关文章

  1. Python 7 —— 扩展与嵌入

    Python 7 —— 扩展与嵌入 所谓扩展是指,在Python当中调用其他语言,由于Python的问题主要是效率,这里的扩展主要是指扩展C C++程序(重点) 所谓嵌入是指,在其他语言当中可以调用P ...

  2. windows 下 使用codeblocks 实现C语言对python的扩展

    本人比较懒就粘一下别人的配置方案了 从这开始到代码 摘自http://blog.csdn.net/yueguanghaidao/article/details/11538433 一直对Python扩展 ...

  3. Python之美[从菜鸟到高手]--一步一步动手给Python写扩展(异常处理和引用计数)

    我们将继续一步一步动手给Python写扩展,通过上一篇我们学习了如何写扩展,本篇将介绍一些高级话题,如异常,引用计数问题等.强烈建议先看上一篇,Python之美[从菜鸟到高手]--一步一步动手给Pyt ...

  4. Python3.x:python: extend (扩展) 与 append (追加) 的区别

    Python3.x:python: extend (扩展) 与 append (追加) 的区别 1,区别: append() 方法向列表的尾部添加一个新的元素.只接受一个参数: extend()方法只 ...

  5. python基础扩展(二)

    python基础扩展(二) 常用操作 1.startswith(以什么开始) endswith(y)什么结束 s='taiWanw39dd' print(s.startswith('t')) #意思是 ...

  6. Python之扩展包安装

    读者朋友,在比较新的版本(Python 2 >=2.7.9 or Python 3 >=3.4)中,pip或者easy_install 扩展包命令已经默认安装(可查看   你的安装目录\p ...

  7. window环境下安装 pip 工具 【pip为Python的扩展管理工具】

    Python有一些扩展管理工具,例如easy_install和pip工具,我推荐各位使用pip工具,因为pip工具具有很好的安装和卸载体验. 我们首先需要打开pip的官方网站, 下载必要的文件包,然后 ...

  8. Python 数据处理扩展包: numpy 和 pandas 模块介绍

    一.numpy模块 NumPy(Numeric Python)模块是Python的一种开源的数值计算扩展.这种工具可用来存储和处理大型矩阵,比Python自身的嵌套列表(nested list str ...

  9. Python和C++的混合编程(使用Boost编写Python的扩展包)

    想要享受更轻松愉悦的编程,脚本语言是首选.想要更敏捷高效,c++则高山仰止.所以我一直试图在各种通用或者专用的脚本语言中将c++的优势融入其中.原来贡献过一篇<c++和js的混合编程>也是 ...

随机推荐

  1. 201521123039《Java程序设计》 第六周学习总结

    1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 1.2 可选:使用常规方法总结其他上课内容. 答:1.cl ...

  2. 201521123039 《java程序设计》第三周学习总结

    1.本周学习总结 2.书面作业 (1)代码阅读 public class Test1 { private int i = 1;//这行不能修改 private static int j = 2; pu ...

  3. python类型转换、数值操作(收藏)

    最近学习python语言,碰到数据类型间的转换问题.看到一篇文章总结的挺详细,收藏之备用. 类型转换 代码  1 函数                      描述  2 int(x [,base  ...

  4. 关于百度DNS的解析过程

    if现在我用一台电脑,通过ISP接入互联网,那么ISP就会分配给我一个DNS服务器(非权威服务器). now,我的computer向这台ISPDNS发起请求查询www.baidu.com. 首先,IS ...

  5. 201521123038 《Java程序设计》 第十四周学习总结

    201521123038 <Java程序设计> 第十四周学习总结 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多数据库相关内容. 接口: DriverManager ...

  6. 【SQL】- 基础知识梳理(三) - SQL连接查询

    一.引言 有时为了得到一张报表的完整数据,需要从两个或更多的表中获取结果,这时就用到了"连接查询". 二.连接查询 连接查询的定义: 数据库中的表通过键将彼此联系起来,从而获取这些 ...

  7. 一款简单而不失强大的前端框架——【Vue.js的详细入门教程①】

    ↓— Vue.js框架魅力 —↓ 前言       Vue.js 是一个构建数据驱动的 web 界面的渐进式框架.Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件.V ...

  8. String类的一些常见的比较方法(4)

    1:boolean equals(Object obj); //比较字符穿的内容是否相同 区分大小写的 2:boolean equalsIgnoreCase(String str); //比较字符穿的 ...

  9. java从命令行接收多个数字,求和程序分析

    问题:编写一个程序,此程序从命令行接收多个数字,求和之后输出结果. 1.设计思想 (1)声明两个变量接收输入的字符串 (2)将字符串转换成int类型 (3)输出求和 2.程序流程图 3.源程序代码 i ...

  10. Python uwsgi 无法安装以及编译报错的处理方式

    之前安装uwsgi的时候编译一步有出错,因为比较早,部分错误代码已经找不到了,网上找了部分错误信息, 现把解决方式共享出来. 环境:CentOS release 6.4   Python 2.7.3 ...