我一直在做一个项目,我必须在触发模式下使用全局快门相机找到对象的 x 和 y 坐标。
到目前为止,一切正常,我得到了想要的结果,但问题是当我在触发模式下连续处理图像时,我得到的图像的额外读数很少。
源图像:
任何人都可以建议我用一个好的方法来解决这个问题。
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 提供的解决方案运行良好,但使用此图像我无法识别对象。
最佳答案
我备份您的源图像,避免您替换或删除它。
我在不同的 ColorSpace 中分析图像,发现 B(BGR)
channel 适合您的任务。
然后执行以下步骤:
代码和结果。
#!/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)
类似的问题:
(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/