python - 将opencv c++代码转换为opencv python代码
问题描述
您好,我有以下 c++ 代码并想将其转换为 python 代码,但是对于 cv2,opencv 函数在 python 中不可用。我怎样才能改变它?我认为这是来自 opencv 的旧功能。这是从视频中删除背景的功能。我正在使用带有 python 的 opencv 版本 4。
#include "stdafx.h"
#include "RunningGaussianAverage.h"
RunningGaussianAverage::RunningGaussianAverage()
{
learningRate = 5;
K = 20;
Imu = ImuNext = NULL;
Isigma = IsigmaNext = NULL;
}
void RunningGaussianAverage::runningGaussianAverage( CvCapture *capture )
{
CvSize sz;
double alpha, k;
IplImage *frameTemp, *frame, *Itemp1, *Itemp2, *Itemp_StdDeviation, *Itemp3;
cvNamedWindow("Original");
cvNamedWindow("Running Gaussian Average");
cvCreateTrackbar("LearningRate", "Running Gaussian Average", &learningRate, 100, NULL);
cvCreateTrackbar("K", "Running Gaussian Average", &K, 100, NULL);
frameTemp = cvQueryFrame(capture);
sz = cvGetSize(frameTemp);
Imu = cvCreateImage(sz, IPL_DEPTH_8U, 1);
ImuNext = cvCreateImage(sz, IPL_DEPTH_8U, 1);
Isigma = cvCreateImage(sz, IPL_DEPTH_8U, 1);
IsigmaNext = cvCreateImage(sz, IPL_DEPTH_8U, 1);
frame = cvCreateImage(sz, IPL_DEPTH_8U, 1);
Itemp1 = cvCreateImage(sz, IPL_DEPTH_8U, 1);
Itemp2 = cvCreateImage(sz, IPL_DEPTH_8U, 1);
Itemp_StdDeviation = cvCreateImage(sz, IPL_DEPTH_32F, 1);
Itemp3 = cvCreateImage(sz, IPL_DEPTH_32F, 1);
cvZero(Imu);
cvZero(ImuNext);
cvZero(Isigma);
cvZero(IsigmaNext);
cvCvtColor(frameTemp, Itemp1, CV_RGB2GRAY);
frameTemp = cvQueryFrame(capture);
cvCvtColor(frameTemp, frame, CV_RGB2GRAY);
cvAbsDiff(frame, Itemp1, Imu);
cvAdd(frame, Itemp1, Isigma);
cvConvertScale(Isigma, Isigma, 0.5);
cvSub(frame, Isigma, Itemp1);
cvSub(Itemp1, Isigma, Itemp2);
cvMul(Itemp1, Itemp1, Itemp1);
cvMul(Itemp2, Itemp2, Itemp2);
cvAdd(Itemp1, Itemp2, Isigma);
cvConvertScale(Isigma, Isigma, 0.5);
while (1) {
alpha = learningRate / 100.0;
k = K / 10.0;
//Calculate μ(t+1) = αF(t) + (1-α)μ(t)
cvConvertScale(frame, Itemp1, alpha);
cvConvertScale(Imu, Itemp2, 1 - alpha);
cvAdd(Itemp1, Itemp2, ImuNext);
//Calculate [σ(t+1)]^2 = α[F(t) - μ(t)]^2 + (1-α)[σ(t)]^2
cvSub(frame, Imu, Itemp1);
cvMul(Itemp1, Itemp1, Itemp1);
cvConvertScale(Itemp1, Itemp1, alpha);
//---
cvConvertScale(Isigma, Itemp2, 1 - alpha);
//---
cvAdd(Itemp1, Itemp2, IsigmaNext);
//Evaluate |F-μ|>Kσ
cvAbsDiff(frame, Imu, frame);
//---
cvConvertScale(Isigma, Itemp_StdDeviation, 1);
cvPow(Itemp_StdDeviation, Itemp_StdDeviation, 0.5);
cvConvertScale(Itemp_StdDeviation, Itemp_StdDeviation, k);
//---
cvConvertScale(frame, Itemp3, 1);
cvCmp(Itemp3, Itemp_StdDeviation, frame, CV_CMP_GT);
cvShowImage("Original", frameTemp);
cvShowImage("Running Gaussian Average", frame);
char c = cvWaitKey(33);
if (c == 27)
break;
cvCopy(ImuNext, Imu);
cvCopy(IsigmaNext, Isigma);
frameTemp = cvQueryFrame(capture);
if (!frameTemp)
break;
cvCvtColor(frameTemp, frame, CV_RGB2GRAY);
}
cvReleaseImage(&frame);
cvReleaseImage(&Itemp1);
cvReleaseImage(&Itemp2);
cvReleaseImage(&Itemp3);
cvReleaseImage(&Itemp_StdDeviation);
cvDestroyWindow("Original");
cvDestroyWindow("Running Gaussian Average");
deallocateImage();
}
void RunningGaussianAverage::deallocateImage()
{
cvReleaseImage(&Imu);
cvReleaseImage(&ImuNext);
cvReleaseImage(&Isigma);
cvReleaseImage(&IsigmaNext);
}
解决方案
我使用以下转换表为您的函数创建了一个类:
# cvQueryFrame --> retval, img = cv2.VideoCapture.read([image]) # cvGetSize --> rows, cols, _ = img.shape # cvCreateImage --> numpy.zeros((w,h,d), dtype='type') # cvZero --> numpy.ndarray.fill(0) <- you can merge this with the previous line # cvCvtColor --> cv2.cvtColor(src, dst, cv2.COLOR_...) # cvAbsDiff --> dst = numpy.absolute(src1, src2) # cvAdd --> cv2.add(src1, src2, dst) or dst = src1 + src2 # cvMul --> cv2.multiply(src1, src2, dst, ...) or dst = numpy.multiply(src1, src2) # cvPow --> dst = math.sqrt(src) # cvCmp --> cv2.compare(src1, src2, dst, criterion)
决定cvPow()
是因为您只使用它一次来执行sqrt()
.
还将代码从 opencv 2.x 更新到 opencv 4.x 再到 python 引入了一些差异:你没有显式使用类型,在真正使用它们之前不需要声明变量,::
并且->
成为.
,等等. 两个版本的许多函数名称也发生了一些变化。这并不容易。
class RunningGaussianAverage:
def __init__(self):
self.learningRate = 5
self.K = 20
self.Imu = None
self.ImuNext = None
self.Isigma = None
self.IsigmaNext = None
def runningGaussianAverage(self, capture):
# GUI part
cv2.namedWindow("Original")
cv2.namedWindow("Running Gaussian Average")
cv2.createTrackbar("LearningRate", "Running Gaussian Average", self.learningRate, 100, None)
cv2.createTrackbar("K", "Running Gaussian Average", self.K, 100, None)
retval, frameTemp = cv2.VideoCapture(capture).read() # get frame
h = frameTemp.shape[0] # substitute of 'sz'
w = frameTemp.shape[1] # substitute of 'sz'
# init everything to empty frames
self.Imu = np.zeros((h, w, 1), np.uint8) # cvCreateImage(sz, IPL_DEPTH_8U, 1)
self.ImuNext = np.zeros((h, w, 1), np.uint8) # i replaced it trying to create a black image, 1 channel
self.Isigma = np.zeros((h, w, 1), np.uint8)
self.IsigmaNext = np.zeros((h, w, 1), np.uint8)
Itemp2 = np.zeros((h, w, 1), np.uint8)
# warning! opencv uses BGR convention!
Itemp1 = cv2.cvtColor(frameTemp, cv2.COLOR_BGR2GRAY) # convert to grayscale
retval, frameTemp = cv2.VideoCapture(capture).read # get another frame
frame = cv2.cvtColor(frameTemp, cv2.COLOR_BGR2GRAY) # convert to grayscale
self.Imu = np.absolute(frame, Itemp1) # absdiff
# using opencv functions
cv2.add(frame, Itemp1, self.Isigma)
self.Isigma = self.Isigma * 0.5 # cvConvertScale(Isigma, Isigma, 0.5)
cv2.subtract(frame, self.Isigma, Itemp1)
cv2.subtract(Itemp1, self.Isigma, Itemp2)
cv2.multiply(Itemp1, Itemp1, Itemp1)
cv2.multiply(Itemp2, Itemp2, Itemp2)
cv2.add(Itemp1, Itemp2, self.Isigma)
self.Isigma = self.Isigma * 0.5 # cvConvertScale(Isigma, Isigma, 0.5)
# using numpy arrays
# self.Isigma = frame + Itemp1
# self.Isigma = self.Isigma * 0.5
# Itemp1 = frame - self.Isigma
# Itemp2 = Itemp1 - self.Isigma
# Itemp1 = Itemp1 * Itemp1
# Itemp2 = Itemp2 * Itemp2
# self.Isigma = Itemp1 + Itemp2
# self.Isigma = self.Isigma * 0.5
while True:
alpha = self.learningRate / 100.0
k = self.K / 10.0
# Calculate μ(t+1) = αF(t) + (1-α)μ(t)
Itemp1 = frame * alpha
Itemp2 = self.Imu * (1 - alpha)
# self.ImuNext = Itemp1 + Itemp2
cv2.add(Itemp1, Itemp2, self.ImuNext)
# Calculate[σ(t+1)] ^ 2 = α[F(t) - μ(t)] ^ 2 + (1-α)[σ(t)] ^ 2
# Itemp1 = frame - self.Imu
# Itemp1 = Itemp1 * Itemp1
cv2.subtract(frame, self.Imu, Itemp1)
cv2.multiply(Itemp1, Itemp1, Itemp1)
Itemp1 = Itemp1 * alpha
# ---
Itemp2 = self.Isigma * (1 - alpha)
# ---
cv2.add(Itemp1, Itemp2, self.IsigmaNext)
# self.IsigmaNext = Itemp1 + Itemp2
# Evaluate | F-μ | > Kσ
frame = np.absolute(frame, self.Imu) # absdiff
# frame = abs(frame - self.Imu)
# ---
Itemp_StdDeviation = np.zeros((h, w, 1), np.float)
Itemp_StdDeviation = self.Isigma * 1
Itemp_StdDeviation = math.sqrt(Itemp_StdDeviation)
Itemp_StdDeviation = Itemp_StdDeviation * k
# ---
Itemp3 = np.zeros((h, w, 1), np.float)
Itemp3 = frame * 1
frame = cv2.compare(Itemp3, Itemp_StdDeviation, cv2.CMP_GT)
cv2.imshow("Original", frameTemp)
cv2.imshow("Running Gaussian Average", frame)
c = cv2.waitKey(33)
if c == 27:
break
self.Imu = self.ImuNext.copy()
self.Isigma = self.IsigmaNext.copy()
retval, frameTemp = cv2.VideoCapture(capture).read() # get another frame
if not frameTemp:
break
cv2.cvtColor(frameTemp, frame, cv2.COLOR_BGR2GRAY)
frame = None
Itemp1 = None
Itemp2 = None
cv2.destroyWindow("Original")
cv2.destroyWindow("Running Gaussian Average")
self.deallocateImage()
def deallocateImage(self):
# don't know if you need the following because of the garbage collector
self.Imu = None
self.ImuNext = None
self.Isigma = None
self.IsigmaNext = None
推荐阅读
- date - 在 Azure 数据工厂 v2 中读取文件时,如何从文件名(即日期)中提取子字符串?
- sql - 我可以选择 SQL Server 中的所有内置函数吗?
- node.js - tsd reinstall:类型定义`index.d.ts`不存在。创建一个并重试
- r - 如果数据超过 R 中的三个 sigma,则用中位数替换数据
- sql - 查询优化 - 左连接中的子选择
- networking - 使网络请求似乎来自连接的 PC 而不是来自移动设备
- scheduler - 计划作业的 Rundeck 详细信息
- plot - 当位置以八度音程更改时,图例属性不会更改
- c# - 从 .NET 中的 word 文档中读取数据
- python - 如何生成多级 Viber 键盘