在python中从BackgroundSubtractorMOG2获取背景模型
我需要得到高斯和opencv混合的背景模型。我知道如果有可能在Python接口中找到它,在C++中有一个方法叫做GETBACKGRUMEDIMAGE,但我没有得到好的结果。我尝试了opencv 3.0.0-dev,因为它有BackgroundSubtractorMOG2实现,但help()函数并没有记录后台模型的方法实现。您知道是否存在未记录的实现吗?我搜索了如何编辑opencv源代码来实现python实现,但还没有找到相关文档。我更喜欢避免使用ScPi.Weave编译C++代码,而且我不知道SyPy.WaveWin对于情况下是有用的。 < P>这是一个使用CyType的简单包装器,我只在Windows 上进行了测试。 cpp,编译为dll在python中从BackgroundSubtractorMOG2获取背景模型,python,opencv,mog,Python,Opencv,Mog,我需要得到高斯和opencv混合的背景模型。我知道如果有可能在Python接口中找到它,在C++中有一个方法叫做GETBACKGRUMEDIMAGE,但我没有得到好的结果。我尝试了opencv 3.0.0-dev,因为它有BackgroundSubtractorMOG2实现,但help()函数并没有记录后台模型的方法实现。您知道是否存在未记录的实现吗?我搜索了如何编辑opencv源代码来实现python实现,但还没有找到相关文档。我更喜欢避免使用ScPi.Weave编译C++代码,而且我不知道S
#include "opencv2/opencv.hpp"
cv::BackgroundSubtractorMOG2 mog(100, 16, false);
cv::Mat bg;
cv::Mat fg;
extern "C" __declspec(dllexport) unsigned char* getfg(int rows,int cols, unsigned char* fdata)
{
cv::Mat frame= cv::Mat(rows, cols, CV_8UC3,fdata);
mog(frame,fg);
//check fg.iscont(), copy as needed
return fg.data;
}
extern "C" __declspec(dllexport) unsigned char* getbg()
{
mog.getBackgroundImage(bg);
return bg.data;
}
蟒蛇
import cv2
import numpy as np
import ctypes as C
lib = C.cdll.LoadLibrary('wrapper.dll')
def getfg(img):
ptr = lib.getfg(img.shape[0],img.shape[1],img.ctypes.data_as(C.POINTER(C.c_ubyte)))
buf = (C.c_ubyte * img.shape[0] * img.shape[1] * 1).from_address(ptr)
res = np.ndarray(buffer=buf, dtype=np.uint8,
shape=(img.shape[0], img.shape[1], 1))
return res
def getbg(img):
ptr = lib.getbg()
buf = (C.c_ubyte * img.shape[0] * img.shape[1] * 3).from_address(ptr)
res = np.ndarray(buffer=buf, dtype=np.uint8,
shape=(img.shape[0], img.shape[1], 3))
return res
c = cv2.VideoCapture(0)
while(1):
_,f = c.read()
cv2.imshow('f',f)
cv2.imshow('fg',getfg(f))
cv2.imshow('bg',getbg(f))
if cv2.waitKey(1)==27:
exit(0)
改编了Zaw Lin的解决方案
- Ubuntu 18.04
- OpenCV 3.2通过
apt安装libopencv dev安装
mog2.cpp:
#包括
cv::BackgroundSubtractorMOG2*mog=cv::createBackgroundSubtractorMOG2(500,16,false);
外部“C”void getfg(int行、int列、无符号字符*imgData、,
无符号字符*fgD){
cv::Mat img(行、列、cv_8UC3,(空*)imgData);
cv::材料fg(行、列、cv_8UC1、fgD);
mog->应用(img、fg);
}
外部“C”void getbg(整数行、整数列、无符号字符*bgD){
cv::Mat bg=cv::Mat(行、列、cv_8UC3、bgD);
mog->getBackgroundImage(背景图像);
}
将其编译为:
gcc\
-共享\
-o libmog2.so\
-fPIC./mog2.cpp\
-lopencv_核心-lopencv_highgui-lopencv_对象检测-lopencv_imgproc-lopencv_功能2D-lopencv_ml-lopencv_calib3d-lopencv_视频
然后是python:
mog2.py
import numpy as np
import ctypes as C
import cv2
libmog = C.cdll.LoadLibrary('path/to/libmog2.so')
def getfg(img):
(rows, cols) = (img.shape[0], img.shape[1])
res = np.zeros(dtype=np.uint8, shape=(rows, cols))
libmog.getfg(img.shape[0], img.shape[1],
img.ctypes.data_as(C.POINTER(C.c_ubyte)),
res.ctypes.data_as(C.POINTER(C.c_ubyte)))
return res
def getbg(img):
(rows, cols) = (img.shape[0], img.shape[1])
res = np.zeros(dtype=np.uint8, shape=(rows, cols, 3))
libmog.getbg(rows, cols, res.ctypes.data_as(C.POINTER(C.c_ubyte)))
return res
if __name__ == '__main__':
c = cv2.VideoCapture(0)
while 1:
_, f = c.read()
cv2.imshow('f', f)
cv2.imshow('fg', getfg(f))
cv2.imshow('bg', getbg(f))
if cv2.waitKey(1) == 27:
exit(0)
opencv 3.0
bgd=dict(history=20,nmixtures=20,backgroundRatio=0.5,noiseSigma=0)
fgbg=cv2.bgsegm.createBackgroundSubtractorMOG(**bgd)
试试这个:我正在使用opencv 3.0.0-dev,因为我已经阅读了您建议的链接……现在我正在尝试理解opencv python解析器是如何工作的……否则,如果没有其他解决方案,我认为我应该用python APIC编写MOG2的包装器——也许类似这样的东西就足够了<代码>背景=0.99*bg+0.01*(边框和~cv2.cvtColor(fg,cv2.COLOR_GRAY2BGR));cv2.imshow('bg',bg/255)MOG2绑定在opencv 3-dev中已经可用。那你为什么要编写自己的呢?@AbidRahmanK MOG2绑定在opencv 3-dev中还没有我需要的背景图片。我在Mac OS X上,我删除了u declspec(ddlexport)并创建了一个动态库。ctypes可以工作,但我在getfg(f)的imshow上遇到了分段错误。我需要一段时间才能接触到mac,我不熟悉mac编程,但我在ubuntu上试用过,效果很好。你能在ubuntu上试试吗?如果你还有问题,我可以更新更多细节。我已经用Python C API编写了一个包装器,但是你的是最好的解决方案。我将尝试强制它在我的系统上工作:)删除
\uu declspec(dllexport)
使它可以在Ubuntu上编译(作为共享库,所有opencv库都添加了-l)。尽管我的问题是无法从返回的地址加载映像。行np.ndarray(buffer=buf[…])
因SIG_SEGV(分段故障)而失败.有什么想法吗?@ZawLin,我现在很长时间都在尝试在windows上构建wrapper.dll文件。它只是不起作用。我安装了opencv,并尝试使用以下命令编译:gcc-o fgbg.dll mog2.cpp-ic:/opencv3.4.10/opencv/build/include-ic:/opencv3.4.10/opencv/build/include/opencv2-lc:/opencv3.4.10/opencv/x64/vc14/lib
它给我的错误如下`对cv::String::allocate的未定义引用(unsigned int)'c:/mingw/bin/./lib/gcc/mingw32/9.2.0/../../../../../../../../mingw32/bin/ld.exe:
请您解释一下如何构建wrapper.dll好吗?谢谢,我用一个静态编译的opencv版本对它进行了测试。所以我们花了一段时间用共享库对它进行了测试。re Emanuel:更正的错误:shape=(行,列,列,1)getfg
中的应仅为shape=(行,列)
。如果将res
包装(转换)为SimpleCVImage
(使用Image(res)
),则会导致错误.更新answer@Matyas我不能编译C++代码到LIMOG2.2文件。我一直在获得错误“opencv2/opencv.Hpp:HungEng/Directory”。我使用Windows 10。我尝试添加<代码>包含“C:/OpenCV2/OpenCV.HPP”。但是没有运气。你能分享一下你是如何解决这个问题的吗?嘿,文德塔,我重新检查了UBUTU18.04的编译;OpenCV3.2更新了C++编译的工作。你有一个更一般的问题,你的安装头文件没有被发现/检测,所以你应该看看如何在Windows中配置它。自从linux/ubuntu开箱即用以来,我就没有经历过这些步骤。