python - 使用 opencv 确定用于拾取和放置的产品的方向
问题描述
我正在尝试检测产品的方向,因此我可以将此方向用于拾取和放置系统。
- 我可以检测到产品的轮廓
- 我可以计算轮廓的中心
- 我可以通过在轮廓上拟合椭圆来计算角度,但是结果并不稳定。
问题在于角度的确定,因为产品在上侧和下侧的质量几乎相同。通过拟合椭圆来计算角度是不稳定的。有时向量指向左,有时指向右。如下图所示,您可以在下图(https://answers.opencv.org/upfiles/15684659369233735.png)中看到,绘制的角度线并不总是指向同一个方向。
到目前为止,这是我的代码:
import cv2
import numpy as np
import math
# read the image
cap = cv2.imread("20190909_170137.jpg")
def nothing(x):
pass
# create slider
cv2.namedWindow("Trackbars")
hh='Max'
hl='Min'
wnd = 'Colorbars'
cv2.createTrackbar("threshold", "Trackbars", 150, 255, nothing)
cv2.createTrackbar("Houghlines", "Trackbars", 255, 255, nothing)
while True:
frame = cv2.imread("20190909_170137.jpg", cv2.IMREAD_COLOR)
scale_percent = 60 # percent of original size
width = int(frame.shape[1] * scale_percent / 100)
height = int(frame.shape[0] * scale_percent / 100)
dim = (width, height)
# resize image
frame = cv2.resize(frame, dim, interpolation = cv2.INTER_AREA)
# create sliders for variables
l_v = cv2.getTrackbarPos("threshold", "Trackbars")
u_v = cv2.getTrackbarPos("Houghlines", "Trackbars")
#convert frame to Black and White
bw = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
#convert Black and White to binary image
ret,thresh4 = cv2.threshold(bw,l_v,255,cv2.THRESH_BINARY)
#find the contours in thresh4
im2, contours, hierarchy = cv2.findContours(thresh4, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
#calculate with contour
for contour in contours:
#calculate area and moment of each contour
area = cv2.contourArea(contour)
M = cv2.moments(contour)
if M["m00"] > 0:
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
#Use contour if size is bigger then 1000 and smaller then 50000
if area > 1000:
if area <50000:
approx = cv2.approxPolyDP(contour, 0.001*cv2.arcLength(contour, True), True)
#draw contour
cv2.drawContours(frame, contour, -1, (0, 255, 0), 3)
#draw circle on center of contour
cv2.circle(frame, (cX, cY), 7, (255, 255, 255), -1)
perimeter = cv2.arcLength(contour,True)
approx = cv2.approxPolyDP(contour, 0.04 * perimeter, True)
#fit elipse
_ ,_ ,angle = cv2.fitEllipse(contour)
P1x = cX
P1y = cY
length = 35
#calculate vector line at angle of bounding box
P2x = int(P1x + length * math.cos(math.radians(angle)))
P2y = int(P1y + length * math.sin(math.radians(angle)))
#draw vector line
cv2.line(frame,(cX, cY),(P2x,P2y),(255,255,255),5)
#output center of contour
print (P1x , P2y, angle)
#detect bounding box
rect = cv2.minAreaRect(contour)
box = cv2.boxPoints(rect)
box = np.int0(box)
#draw bounding box
cv2.drawContours(frame, [box],0,(0,0,255),2)
#Detect Hull
hull = cv2.convexHull(contour)
#draw line
#img_hull = cv2.drawContours(frame,[hull],0,(0,0,255),2)
#print (angle)
# print (p)
cv2.imshow("Frame", thresh4)
key = cv2.waitKey(1)
cv2.imwrite('thresh4.png',thresh4)
key = cv2.waitKey(1)
cv2.imshow("bw2", frame)
key = cv2.waitKey(1)
cv2.imwrite('box.png',frame)
key = cv2.waitKey(1)
key = cv2.waitKey(1)
#if key == 27:
# break
break
#cap.release()
cv2.destroyAllWindows()
有人知道我如何确保角度(方向)的计算是 100% 正确的。
您可以在以下链接中找到示例图片:
解决方案
推荐阅读
- java - @RequestMapping 无法正常工作
- excel - 如何使用数据透视表对变量求和,但子类在哪里重复行?
- visual-studio-code - 如何更改 VS Code 设置以使用 JetBrains Mono 字体
- react-native - 如何以声明性方式使用 react-native-reanimated 启动“spring”动画?
- android - Android 导航深层链接 - 忽略查询
- spring - 当接收到“+”运算符作为参数时,如何避免@RequestParam 连接?
- python - 从 dict 值实例化类的漂亮方法
- powerapps - 启用下拉按钮和文本输入验证
- python - 带有二进制数的 QSpinbox
- java - Java BlockingQueue - 进程不想停止