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. 团队作业4——第一次项目冲刺(Alpha版本)4.25

    团队作业4--第一次项目冲刺(Alpha版本) Day four: 会议照片 每日站立会议: 项目进展 今天是项目的Alpha敏捷冲刺的第四天,先大概整理下昨天已完成的任务以及今天计划完成的任务.今天 ...

  2. 201521123078 《Java程序设计》第6周学习总结

    1. 本周学习总结 2. 书面作业 1.clone方法 1.1 Object对象中的clone方法是被protected修饰,在自定义的类中覆盖clone方法时需要注意什么? 1.子类要实现Clone ...

  3. JAVA课程设计猜数游戏 个人

    1.团队课程设计博客链接 https://i.cnblogs.com/EditPosts.aspx?postid=7067843&update=1 2.个人负责模块说明 输入用户ID 2.主要 ...

  4. 201521123051《Java程序设计》第九周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. ·所有的异常类是从 java.lang.Exception 类继承的子类. ·Exception 类是 Throwa ...

  5. 201521123106 《Java程序设计》第13周学习总结

    1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 书面作业 1. 网络基础 1.1 比较ping www.baidu.com与ping cec.jmu ...

  6. JAVA课程设计-学生信息管理系统(个人博客)

    1. 团队课程设计博客链接 http://www.cnblogs.com/Min21/p/7064093.html 2.个人负责模块或任务说明 负责person类的编写,建立person对象, 完成M ...

  7. Jquery第三篇【AJAX 相关的API】

    前言 前面我们已经学了讲解了Jquery的选择器,关于DOM 的API还有事件的API.本博文需要讲解Jquery对AJAX的支持- 我们在开始使用JavaScript学习AJAX的时候,创建异步对象 ...

  8. hibernate中Query的list和iterator区别

    1.Test_query_list类 public class Test_query_iterator_list { public static void main(String[] args) { ...

  9. ambari

    http://blog.csdn.net/ggz631047367/article/details/50491616 https://cwiki.apache.org/confluence/displ ...

  10. mysql水平分表和垂直分表的优缺点

    表分割有两种方式: 1.水平分割:根据一列或多列数据的值把数据行放到两个独立的表中. 水平分割通常在下面的情况下使用. •表很大,分割后可以降低在查询时需要读的数据和索引的页数,同时也降低了索引的层数 ...