Quantcast
Channel: OpenCV Q&A Forum - RSS feed
Viewing all articles
Browse latest Browse all 2088

How to determine the length of contours?

$
0
0
Hello, I'm actually working on a webcam software with which I will control a UR co-bot to pick and place objects about forms and colors. I'm working with Python and OpenCV, I managed to recognize the shapes with the `findcountor` and `drawcontour` function, and I sort them with the `approxPolyDP` function. Now I would like to determine for instance the length of each side of a rectangle and then calculate the middle of a side and that point will be sent to the robot to catch it with the gripper. I tried a lot of things and I searched on a lot of forums but I didn't got any usable information, if you have any idea please let me know. Here is my code: import cv2 import numpy as np import imutils from shapeDetector import ShapeDetector import shapely.geometry as shapgeo lower = {'red':(169, 100, 100), 'blue':(108, 100, 100), 'yellow':(18, 100, 100), 'green':(59, 100, 100)} upper = {'red':(189, 255, 255), 'blue':(128, 255, 255), 'yellow':(54, 255, 255), 'green':(79, 255, 255)} colors = {'red':(0,0,255), 'blue':(255,0,0), 'yellow':(38, 255, 255), 'green':(0, 255, 0)} camera = cv2.VideoCapture(0) def drawContours(frame,c): (x,y,w,h) = cv2.boundingRect(c) if w > 50 and h > 50: cv2.drawContours(frame, [c], -1, colors[key], 2) cv2.circle(frame, (cX, cY), 7, (255, 255, 255), -1) cv2.putText(frame, "center", (cX - 20, cY - 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255,255,255),2) cv2.putText(frame, shape, (cX + 20, cY + 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2) c = c.astype("float") c *= ratio c = c.astype("int") cv2.imshow("Frame", frame) return frame while True: (grabbed, frame) = camera.read() resized = imutils.resize(frame, width=600) ratio = frame.shape[0] / float(resized.shape[0]) blurred = cv2.GaussianBlur(frame, (11,11), 0) hsv = cv2.cvtColor(blurred, cv2.COLOR_BGR2HSV) for key, value in upper.items(): kernel = np.ones((9,9),np.uint8) mask = cv2.inRange(hsv, lower[key], upper[key]) mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel) mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel) #mask = cv2.morphologyEx(mask, cv2.MORPH_GRADIENT, kernel) cnts = cv2.findContours(mask.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE) cnts = cnts[0] if imutils.is_cv2() else cnts[1] sd = ShapeDetector() for c in cnts: M = cv2.moments(c) cX = int((M["m10"] / M["m00"]) * ratio) cY = int((M["m01"] / M["m00"]) * ratio) shape = sd.detect(c) drawContours(frame, c) #cv2.imshow("mask",mask) key = cv2.waitKey(1) & 0xFF if key == ord("q"): break camera.release() cv2.destroyAllWindows() **Here is the shape detection:** import cv2 class ShapeDetector: def __init__(self): pass def detect(self, c): # initialize the shape name and approximate the contour shape = "unidentified" peri = cv2.arcLength(c, True) approx = cv2.approxPolyDP(c, 0.04 * peri, True) # if the shape is a triangle, it will have 3 vertices if len(approx) == 3: shape = "triangle" # if the shape has 4 vertices, it is either a square or # a rectangle elif len(approx) == 4: # compute the bounding box of the contour and use the # bounding box to compute the aspect ratio (x, y, w, h) = cv2.boundingRect(approx) ar = w / float(h) # a square will have an aspect ratio that is approximately # equal to one, otherwise, the shape is a rectangle shape = "square" if ar >= 0.95 and ar <= 1.05 else "rectangle" # if the shape is a pentagon, it will have 5 vertices elif len(approx) == 5: shape = "pentagon" # if the shape is a hexagon, it will have 6 vertices elif len(approx) == 6: shape = "hexagon" # otherwise, we assume the shape is a circle else: shape = "circle" # return the name of the shape return shape

Viewing all articles
Browse latest Browse all 2088

Trending Articles