python - 如何在嘈杂的背景中找到物体?

标签 python opencv image-processing

我一直在做一个项目,我必须在触发模式下使用全局快门相机找到对象的 x 和 y 坐标。
到目前为止,一切正常,我得到了想要的结果,但问题是当我在触发模式下连续处理图像时,我得到的图像的额外读数很少。

源图像:

enter image description here

任何人都可以建议我用一个好的方法来解决这个问题。

from scipy.spatial import distance as dist
from imutils import perspective
from imutils import contours
import numpy as np
import argparse
import imutils
import cv2

def midpoint(ptA, ptB):
    return ((ptA[0] + ptB[0]) * 0.5, (ptA[1] + ptB[1]) * 0.5)


image = cv2.imread('022.bmp')
gray = cv2.cvtColor(image,cv2.COLOR_BGR2HSV)
gray = cv2.GaussianBlur(gray,(7,7),0)

edged = cv2.Canny(gray,50,100)
edged = cv2.dilate(edged,None, iterations=1)
edged = cv2.erode(edged, None, iterations=1)

cnts = cv2.findContours(edged.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if imutils.is_cv2() else cnts[1]

(cnts, _) = contours.sort_contours(cnts)
colors = ((0,0,255),(240,0,159),(0,165,255),(255,255,0),(255,0,255))
refObj = None

for c in cnts:
    if cv2.contourArea(c)<250:
        #print "in if loop"
        continue
    #print cv2.contourArea(c)
    box = cv2.minAreaRect(c)
    box = cv2.cv.BoxPoints(box) if imutils.is_cv2() else cv2.boxPoints(box)
    box = np.array(box,dtype="int")

    box = perspective.order_points(box)

    cX = np.average(box[:,0])
    cY = np.average(box[:,1])

    if refObj is None:
        (tl,tr,br,bl) = box
        (tlblX, tlblY) = midpoint(tl,bl)
        (trbrX, trbrY) = midpoint(tr,br)

        D = dist.euclidean((tlblX,tlblY),(trbrX,trbrY))
        refObj = (box, (cX,cY),D)
        print refObj[0]
        print 'cx-1',cX
        print 'cy-1',cY
        continue

orig = image.copy()
cv2.drawContours(orig,[box.astype("int")], -1, (0,255,0), 2)
cv2.drawContours(orig, [refObj[0].astype("int")],-1,(0,255,0),2)

refCoords = np.vstack([refObj[0],refObj[1]])
objCoords = np.vstack([box, (cX,cY)])

print box
print 'cx',cX
print 'cy',cY

for ((xA,yA), (xB,yB), color) in zip(refCoords,objCoords,colors):
    cv2.circle(orig, (int(xA),int(yA)),5,color,-1)
    cv2.circle(orig, (int(xB),int(yB)),5,color,-1)
    cv2.line(orig, (int(xA),int(yA)),(int(xB),int(yB)),color,2)




cv2.imshow('img',orig)
cv2.waitKey(0)

你能就此提出一些建议吗?
谢谢!

更新,@silencer 提供的解决方案运行良好,但使用此图像我无法识别对象。 enter image description here

最佳答案

我备份您的源图像,避免您替换或删除它。



我在不同的 ColorSpace 中分析图像,发现 B(BGR) channel 适合您的任务。

enter image description here

然后执行以下步骤:

  • 读取并提取蓝色 channel 。
  • 阈值蓝色 channel 。
  • 寻找轮廓。
  • 按区域过滤。

  • enter image description here

    代码和结果。
    #!/usr/bin/python3
    # 2017.12.09 00:25:47 CST
    # 2018.01.10 21:10:07 CST
    import cv2
    import numpy as np
    
    
    ## (1) read and extract the blue channel
    img = cv2.imread("img01.png")
    blue = img[...,0]
    
    ## (2) threshold the blue
    th, threshed = cv2.threshold(blue, 200, 255, cv2.THRESH_BINARY_INV|cv2.THRESH_OTSU)
    
    ## (3) find contours
    cnts = cv2.findContours(threshed,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)[-2]
    
    ## (4) filter by AREA
    canvas = img.copy()
    H,W = img.shape[:2]
    AREA = H*W
    
    for cnt in cnts:
        area = cv2.contourArea(cnt)
        if not AREA/100<area<AREA/20:
            continue
        box = cv2.minAreaRect(cnt)
        box = cv2.boxPoints(box)
        box = np.array(box,dtype="int")
        cv2.drawContours(canvas, [box], -1,(255,0,255) , 2, cv2.LINE_AA)
    
    ## save
    cv2.imwrite("result.png", canvas)
    

    enter image description here

    类似的问题:

    (1) How to find the object on the noisy background?

    (2) Python OpenCV - Trying to identify a completely visible tile (all four edges are visible) and draw a green contour edges

    关于python - 如何在嘈杂的背景中找到物体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48181764/

    相关文章:

    image-processing - 如何使用 javacv/opencv 识别黑色多边形上的点?

    python - 在 Python 中使用 Azure AD 下载 Azure 存储数据

    python - Pandas :Dataframe.replace() 与正则表达式

    c++ - 如何计算OpenCV中每个圆圈中的像素数?

    algorithm - 脱毛算法开发

    image - Blob 检测的替代算法

    python - 从方法中重新引发异常作为参数

    python - 如何在python中创建特定类型的数组

    c# - 使用 Kinect 和 EMGU(OpenCV 包装器)定位机器人

    python - 在 OpenCV 中重用 grabcut 模型