我是Python和OpenCV编码的初学者,我的程序有问题。我的目标是检测轨道上的任何障碍物。为了实现这个项目,我正在使用一个函数来替换背景。一开始,我有一个背景和不同的照片,有一个障碍训练。但是一些带有障碍物的照片与我的背景不兼容。
这就是我决定拍摄不同背景照片的原因。我们的想法是创建一个代码,它将使用不同的背景进行减法,直到它真正起作用。这是一个例子:我有一张带有物体的照片。代码将用照片替换照片中的第一个背景。如果它不起作用(代码在此应用程序之后没有检测到对象),那么它将再次尝试使用第二个背景,依此类推。
一旦找到合适的背景来替换照片中的对象(这意味着代码将返回带有围绕对象的矩形的原始照片),然后它就会停止。当然,我们不需要尝试剩下的其他背景,因为我们现在已经有了一个好的结果。
所以我的问题是:我正在尝试使用下面的代码执行此操作,但它不起作用。如果对于具有对象的照片,例如特定背景,则如果循环FOR(第22行)开始处理此背景,则它将起作用,因为循环将在第一次迭代之后停止。但是如果这个背景是第二次迭代或更多,那么它就不再起作用了。我想每次我在这个循环中再次回来时,我会覆盖我创建的最后一帧。我的意思是,而不是在第二次迭代中从“带有对象的照片”中减去“backgorund 2”,我想我从“带有对象和背景1的照片”中减去“backgorund 2”,或类似这样的东西。我不是百分百肯定,但这是一个假设。
如果有人能告诉我为什么它不起作用,我将非常感激。
这是我的代码:
import numpy as np
import cv2
import sys
from time import gmtime, strftime
import time
import os
dirname=str(strftime("%Y-%m-%d %H-%M-%S", time.localtime()))
newpath = "%s" %dirname
if not os.path.exists(newpath):
os.makedirs(newpath)
# both MOG and MOG2 can be used, with different parameter values
backgroundSubtractor = cv2.bgsegm.createBackgroundSubtractorMOG()
# apply the algorithm for background images using learning rate > 0
for i in range(1, 10):
bgImageFile = "background%s.jpg" % i
print ("Opening background", bgImageFile)
bg = cv2.imread(bgImageFile)
backgroundSubtractor.apply(bg)
# apply the algorithm for detection image using learning rate 0
stillFrame = cv2.imread("object1.jpg")
fgmask = backgroundSubtractor.apply(stillFrame, learningRate=0)
cv2.imwrite('%s/fgmask.jpg' %dirname, fgmask)
img1 = cv2.imread('%s/fgmask.jpg' %dirname)
gray=cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)
ret,th2 = cv2.threshold(gray,100,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
morphed = th2.copy()
morphed = cv2.morphologyEx(morphed, cv2.MORPH_ERODE, kernel, iterations=5)
morphed1 = cv2.morphologyEx(morphed, cv2.MORPH_DILATE, kernel, iterations=17)
cv2.namedWindow("image", cv2.WINDOW_NORMAL)
cv2.resizeWindow("image", 1000, 700)
cv2.imshow("image", morphed1)
_, contours,_ = cv2.findContours(morphed1, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = list(filter(lambda cnt: cv2.contourArea(cnt) > 10000 and cv2.arcLength(cnt,True) > 1000, contours))
for cnt in contours:
print("aire = ", cv2.contourArea(cnt))
print("perimetre = ", cv2.arcLength(cnt,True))
rect = cv2.minAreaRect(cnt)
box = cv2.boxPoints(rect)
box = np.int0(box)
cv2.drawContours(stillFrame,[box],0,(0,255,255),10)
if len(contours)>0:
break
# show both images
cv2.namedWindow("image1", cv2.WINDOW_NORMAL)
cv2.resizeWindow("image1", 1000, 700)
cv2.imshow("image1", img1)
cv2.namedWindow("image2", cv2.WINDOW_NORMAL)
cv2.resizeWindow("image2", 1000, 700)
cv2.imshow("image2", stillFrame)
cv2.waitKey()
cv2.destroyAllWindows()
以下是一些照片:
背景:
对象: