xpr*_*edo 5 python opencv image-processing
我有一个盒子,从前面透明,我将相机放在前面的透明面板上捕捉内部的图像,大多数时候盒子是空的,但是假设有人在这个盒子里面放了一个物体,那么我必须只从捕获的图像中提取此对象.
(我的真正目的是识别放置在盒子内的物体,但第一步是提取物体,然后提取特征以生成训练模型,现在我只专注于从图像中提取物体)
我是OpenCV的新手,并且在Python中使用它,我找到了一些可以帮助我的OpenCV函数.
背景减法的代码如下,即使短距离也不能正常工作
cap = cv2.VideoCapture(0)
fgbg = cv2.createBackgroundSubtractorMOG2()
fgbg2 = cv2.createBackgroundSubtractorKNN()
while True:
ret, frame = cap.read()
cv2.namedWindow('Real', cv2.WINDOW_NORMAL)
cv2.namedWindow('MOG2', cv2.WINDOW_NORMAL)
cv2.namedWindow('KNN', cv2.WINDOW_NORMAL)
cv2.namedWindow('MOG2_ERODE', cv2.WINDOW_NORMAL)
cv2.namedWindow('KNN_ERODE', cv2.WINDOW_NORMAL)
cv2.imshow('Real', frame)
fgmask = fgbg.apply(frame)
fgmask2 = fgbg2.apply(frame)
kernel = np.ones((3,3), np.uint8)
fgmask_erode = cv2.erode(fgmask,kernel,iterations = 1)
fgmask2_erode = cv2.erode(fgmask2,kernel,iterations = 1)
cv2.imshow('MOG2',fgmask)
cv2.imshow('KNN',fgmask2)
cv2.imshow('MOG2_ERODE',fgmask_erode)
cv2.imshow('KNN_ERODE',fgmask2_erode)
k = cv2.waitKey(30) & 0xff
if k == 27:
break
cap.release()
cv2.destroyAllWindows()
Run Code Online (Sandbox Code Playgroud)
任何人都可以请帮助这个主题,以及如何修改上面的代码只是使用这两个图像,当我尝试我得到空白图像.提前致谢
来自相机的样本图像如下:(我使用800万像素相机,这就是为什么图像尺寸很大,我减小了尺寸,然后在这里上传)
你提到过减法,我相信在这种情况下它是最好的方法.我已经实现了一个非常简单的算法来处理你提供给我们的案例.我用注释解释了代码.在图像上,我提出了你遇到的最重要的步骤 - 算法的线索.
代码说明:
import cv2
import numpy as np
# load the images
empty = cv2.imread("empty.jpg")
full = cv2.imread("full_2.jpg")
# save color copy for visualization
full_c = full.copy()
# convert to grayscale
empty_g = cv2.cvtColor(empty, cv2.COLOR_BGR2GRAY)
full_g = cv2.cvtColor(full, cv2.COLOR_BGR2GRAY)
# blur to account for small camera movement
# you could try if maybe different values will maybe
# more reliable for broader cases
empty_g = cv2.GaussianBlur(empty_g, (41, 41), 0)
full_g = cv2.GaussianBlur(full_g, (41, 41), 0)
# get the difference between full and empty box
diff = full_g - empty_g
cv2.imwrite("diff.jpg", diff)
# inverse thresholding to change every pixel above 190
# to black (that means without the bag)
_, diff_th = cv2.threshold(diff, 190, 255, 1)
cv2.imwrite("diff_th.jpg", diff_th)
# combine the difference image and the inverse threshold
# will give us just the bag
bag = cv2.bitwise_and(diff, diff_th, None)
cv2.imwrite("just_the_bag.jpg", bag)
# threshold to get the mask instead of gray pixels
_, bag = cv2.threshold(bag, 100, 255, 0)
# dilate to account for the blurring in the beginning
kernel = np.ones((15, 15), np.uint8)
bag = cv2.dilate(bag, kernel, iterations=1)
# find contours, sort and draw the biggest one
_, contours, _ = cv2.findContours(bag, cv2.RETR_TREE,
cv2.CHAIN_APPROX_SIMPLE)
contours = sorted(contours, key=cv2.contourArea, reverse=True)[:3]
cv2.drawContours(full_c, [contours[0]], -1, (0, 255, 0), 3)
# show and save the result
cv2.imshow("bag", full_c)
cv2.imwrite("result2.jpg", full_c)
cv2.waitKey(0)
Run Code Online (Sandbox Code Playgroud)
现在,当然可以改进算法,并且必须根据您必须处理的任何条件进行调整.例如,你已经提到了光照的不同之处 - 你必须处理它以确保减去图像的背景相似.要做到这一点,你可能不得不看一些对比度增强算法,如果相机移动可能会注册 - 这可能是一个完全独立的问题.
我还会考虑一下JeruLuke提到的GrabCut,它是用我的方法找到的轮廓的边界矩形.要确保对象包含在其中,只需展开矩形即可.
| 归档时间: |
|
| 查看次数: |
4754 次 |
| 最近记录: |