def get_point_normal_pixel_coordinates(shape,point_index,nn,npx): point = shape.get_point(point_index) neighborhood = shape.get_neighborhood(point_index, nn) line = cv2.fitLine(neighborhood, cv2.DIST_L2, 0, 0.01, 0.01); slope = line[0:2] / np.sqrt(np.sum(line[0:2] ** 2)) return [[int(point[1] + (incr * slope[0]) + 0.5), int(point[0] - (incr * slope[1]) + 0.5)] for incr in range(-npx, npx + 1)]
def find_lines(self, contours, image): lines = [] for contour in contours: approx = cv2.approxPolyDP(contour, 0, False) area = np.abs(cv2.contourArea(contour)) if self.area_min.get_current_value() < area < self.area_max.get_current_value(): line_values = cv2.fitLine(approx, cv.CV_DIST_L2, 0, 0.01, 0.01) rect = cv2.boundingRect(approx) t0 = t1 = math.sqrt((rect[2]**2 + rect[3]**2) / 2.0) vx,vy,x,y = line_values # CHEAP FIX limit1Found = limit2Found = False while not (limit1Found and limit2Found) and t0 > 0 and t1 > 0: if not limit1Found: if not self.is_point_intersecting((int(x - t0 * vx),int( y - t0 * vy)), image): t0 = t0 - 20 else: limit1Found = True if not limit2Found: if not self.is_point_intersecting((int(x + t1 * vx),int( y + t1 * vy)), image): t1 = t1 - 20 else: limit2Found = True line = (x - t0 * vx, y - t0 * vy, x + t1 * vx, y + t1 * vy ) lines.append(line) cv2.drawContours(image, contour, -1, (255, 255, 0)) return lines
def mapPalmAndFingers(contours, image): handElements = [] for i in xrange(len(contours)): M = cv2.moments(contours[i]) centroid_x = int(M['m10']/M['m00']) centroid_y = int(M['m01']/M['m00']) # cv2.circle(lefthand, (centroid_x, centroid_y), 10, (255, 0, 0),-1) element = { 'center': (centroid_x, centroid_y), 'contour': contours[i], 'area': cv2.contourArea(contours[i]), 'palm': False } handElements.append(element) # mapp the distance of hand elements from the palm palm = max(handElements, key=lambda x: x['area']) palm['palm'] = True palm['dist'] = 0 for handElement in handElements: if handElement['palm'] is False: handElement['dist'] = linalg.norm(np.array(handElement['center']) - np.array(palm['center'])) # sorting the hand helements by the distance from the palm # because this way we will find the end of the fingers handElements = sorted(handElements, key=itemgetter('dist'), reverse=True) rows,cols = image.shape[:2] fingersEnd = [] for handElement in handElements: maskPalm = np.zeros(image.shape, np.uint8) maskLine = np.zeros(image.shape, np.uint8) cv2.drawContours(maskPalm, [palm['contour']], 0, 1, -1) [vx, vy, x, y] = cv2.fitLine(handElement['contour'], cv2.cv.CV_DIST_L2, 0, 0.01, 0.01) lefty = int((-x*vy/vx) + y) righty = int(((cols-x)*vy/vx)+y) cv2.line(maskLine, (cols-1, righty), (0, lefty), 1, 2) cv2.line(image, (cols-1, righty), (0, lefty), 1, 2) result = maskLine * maskPalm cv2.drawContours(maskPalm, [handElement['contour']], 0, 255, 1) cv2.drawContours(maskPalm, [palm['contour']], 0, 255, 1) # cv2.imshow('aaa'+int(handElement['area']),result) plt.figure(int(handElement['area'])) plt.imshow((maskLine + maskPalm), cmap='gray') if np.sum(result) > 0: fingersEnd.append(handElement) # plt.figure(2) # plt.imshow(result, cmap='gray') # plt.show() return fingersEnd, palm
def fitLine_ransac(pts,zero_add = 0 ): if len(pts)>=2: [vx, vy, x, y] = cv2.fitLine(pts, cv2.DIST_HUBER, 0, 0.01, 0.01) lefty = int((-x * vy / vx) + y) righty = int(((136- x) * vy / vx) + y) return lefty+30+zero_add,righty+30+zero_add return 0,0
def drawStuff(centerCordinates, image): # http://opencvpython.blogspot.no/2012/06/contours-2-brotherhood.html # http://docs.opencv.org/3.1.0/dd/d49/tutorial_py_contour_features.html#gsc.tab=0pyth ############## creating a minimum rectangle around the object ###################### rect = cv2.minAreaRect(points=centerCordinates) box = cv2.cv.BoxPoints(rect) box = np.int0(box) cv2.drawContours(image,[box],0,(255,255,255),2) ########### circle around object #######3 (x, y),radius = cv2.minEnclosingCircle(centerCordinates) center = (int(x),int(y)) radius = int(radius) cv2.circle(image, center, radius, (255,255,255),2) ########### finding a elipse ############## ellipse = cv2.fitEllipse(centerCordinates) cv2.ellipse(image,ellipse,(255,255,255),2) ##### fitting a line ########### rows,cols = image.shape[:2] [vx,vy,x,y] = cv2.fitLine(points=centerCordinates, distType=cv2.cv.CV_DIST_L2, param =0, reps=0.01, aeps=0.01) lefty = int((-x*vy/vx) + y) righty = int(((cols-x)*vy/vx)+y) cv2.line(image,(cols-1,righty),(0,lefty),(255,255,255),2) pixelSizeOfObject = radius # an okay estimate for testing return image, pixelSizeOfObject
def test_fitline(self): noise = 5 n = 200 r = 5 / 100.0 outn = int(n*r) p0, p1 = (90, 80), (w-90, h-80) line_points = sample_line(p0, p1, n-outn, noise) outliers = np.random.rand(outn, 2) * (w, h) points = np.vstack([line_points, outliers]) lines = [] for name in dist_func_names: func = getattr(cv2.cv, name) vx, vy, cx, cy = cv2.fitLine(np.float32(points), func, 0, 0.01, 0.01) line = [float(vx), float(vy), float(cx), float(cy)] lines.append(line) eps = 0.05 refVec = (np.float32(p1) - p0) / cv2.norm(np.float32(p1) - p0) for i in range(len(lines)): self.assertLessEqual(cv2.norm(refVec - lines[i][0:2], cv2.NORM_L2), eps)
def detectLine_fromContours_filterByPerimeter(_img, contours, **params): """Summary Args: img (TYPE): Description contours (TYPE): Description **params (TYPE): Description Returns: TYPE: Description """ # minPerimeter = params.get("minPerimeter", 0) maxPerimeter = params.get("maxPerimeter", 10000) thickness = params.get("thickness", 1) color = params.get("color", (255, 255, 255)) # width, height = _img.shape[:2] # for i, contour in enumerate(contours): perimeter = cv2.arcLength(contour, True) if (perimeter >= minPerimeter) and (perimeter <= maxPerimeter): # url: https://github.com/Itseez/opencv/blob/master/samples/python/fitline.py # url: http://stackoverflow.com/questions/14184147/detect-lines-opencv-in-object # then apply fitline() function [vx, vy, x, y] = cv2.fitLine(contour, cv2.DIST_L2, 0, 0.01, 0.01) # [vx, vy, x, y] = cv2.fitLine(contour, cv2.DIST_HUBER, 0, 0.01, 0.01) # Now find two extreme points on the line to draw line lefty = int((-x * vy / vx) + y) righty = int(((width - x) * vy / vx) + y) # Finally draw the line cv2.line(_img, (width - 1, righty), (0, lefty), color, thickness)
def delete_one_edge(self, contour, inliner_idx, d, p): ''' 从contour中删除和第p个未被分配的点在同一条直线上的点,点到直线的最大距离为d @param contour: 轮廓 @param inliner_idx: 当前点已经完成的分配 @param d: 最大偏差 @param p: 中心点的位置 ''' assert isinstance(contour, np.ndarray) counter = 0 center = 0 # when the contour is shorter than p, center will be 0 for k, v in enumerate(inliner_idx): counter = counter + 1 if v == -1 else counter if counter == p: center = k break # TODO: determine Region of Support (ROS) points = get_elements_in_window(contour, center, 2) # get line in format (vx, vy, x0, y0) line = cv2.fitLine(np.asarray(points, dtype=np.float32), cv2.cv.CV_DIST_L2, 0, 0.01, 0.01) vx = line[0] vy = line[1] n = np.asarray([vx, vy]) n = np.squeeze(n) a = np.asarray([line[2], line[3]]) a = np.squeeze(a) self.set_adjacent_inliner(contour, inliner_idx, center, n, a, d) return inliner_idx
def find_line(cap): height = cap.read()[1].shape[0] width = cap.read()[1].shape[1] maxcorners = 6 ret, frame = cap.read() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) gray = cv2.bilateralFilter(gray,9,75,75) corners = cv2.goodFeaturesToTrack(gray,15,0.01,10) corners = np.int0(corners) line_corners = [] counter = 0 for i in corners: x, y = i.ravel() if x > 60 and y > 0 and y < height - 40 and counter < maxcorners: cv2.circle(frame,(x,y),1,(0,0,255),-1) line_corners.append((x,y)) counter += 1 if len(line_corners) == 6: # line_corners.sort(key=lambda tup: -tup[0] + tup[1]) vx, vy, x, y = cv2.fitLine(np.array(line_corners),cv2.cv.CV_DIST_L2,0,0.01,0.01) line = [float(vx),float(vy),float(x),float(y)] left_pt = int((-x*vy/vx) + y) right_pt = int(((gray.shape[1]-x)*vy/vx)+y) cv2.line(frame,(gray.shape[1]-1,right_pt),(0,left_pt),255,2) filename = '/tmp/calibration_' + datetime.datetime.now().strftime("%H:%M:%S.%f") + '.jpg' cv2.imwrite(filename, frame) return line
def vision_run(cap, height, width, points, frames, event, maxcorners = 6): ret, frame = cap.read() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) cv2.imshow('frame', frame) corners = cv2.goodFeaturesToTrack(gray,15,0.01,10) corners = np.int0(corners) line_corners = [] counter = 0 for i in corners: x,y = i.ravel() if x > 60 and x < width - 70 and y > 20 and y < height - 20 and counter < maxcorners: line_corners.append((x,y)) counter += 1 if len(line_corners) == maxcorners: line_corners.sort(key=lambda tup: -tup[0] + tup[1]) vx, vy, x, y = cv2.fitLine(np.array(line_corners),cv2.cv.CV_DIST_L2,0,0.01,0.01) point = [float(vx),float(vy),float(x),float(y)] left_pt = int((-x*vy/vx) + y) right_pt = int(((gray.shape[1]-x)*vy/vx)+y) cv2.line(frame,(gray.shape[1]-1,right_pt),(0,left_pt),255,2) if event == "add": points.append([float(vx),float(vy),float(x),float(y)]) if len(points) > 2: centroid = centroid(points) frames.append(frame)
def _collect_finger_elements(self, finger_end): line_mask = np.zeros(self.imageMap.shape, np.uint8) rows, cols = self.imageMap.shape[:2] [vx, vy, x, y] = cv2.fitLine(finger_end['contour'], cv2.cv.CV_DIST_L2, 0, 0.01, 0.01) lefty = int((-x * vy / vx) + y) righty = int(((cols - x) * vy / vx) + y) cv2.line(line_mask, (cols - 1, righty), (0, lefty), 1, 2) hand_element_mask = np.zeros(self.imageMap.shape, np.uint8) # any finger element which already passed as the flag as true, make the detection easier finger_elements = [finger_end] finger_end['passed'] = True for handElement in self.handElements: if handElement['palm'] is False and handElement['passed'] is False: # set zeros in the mask hand_element_mask.fill(0) cv2.drawContours(hand_element_mask, [handElement['contour']], 0, 1, -1) # plt.figure(1) # plt.imshow(line_mask, cmap='gray') # plt.figure(2) # plt.imshow(hand_element_mask, cmap='gray') # plt.figure(3) # plt.imshow(np.multiply(hand_element_mask,line_mask), cmap='gray') # plt.show() # if the line and the handElement came a cross the max value will be larger than zero if np.multiply(hand_element_mask, line_mask).max() > 0: finger_elements.append(handElement) handElement['passed'] = True return finger_elements
def sortByDirection(contours,direction): if direction not in range(6): direction = 5 if direction!=5: #get the direction vector for every contour directionHist = [0,]*4 contByDirection = [[],[],[],[]] i = 1 for cont in contours: l = cv2.fitLine(cont, cv2.cv.CV_DIST_L2, 0, 0.1, 0.1) v = (l[0],l[1]) index = getDirectionArea(v) contByDirection[index].append(cont) if i: i = 0 directionHist[index]+=1 if direction==4: return contByDirection[directionHist.index(max(directionHist))] else: return contByDirection[direction] return contours
def line_segment(self, ransac_groups): points = [] max_size = 0 idx_max = 0 for idx, value in enumerate(ransac_groups): if len(value) > max_size: idx_max = idx max_size = len(value) print "Index: ", idx_max, "Size: ", max_size if max_size > 0: best_edgels_group = ransac_groups[idx_max] for edgel in best_edgels_group: points.append(edgel.position) print points y = [pos.position[0] for pos in best_edgels_group] x = [pos.position[1] for pos in best_edgels_group] # for xp, yp in zip(x, y): # cv2.circle(self.__image, (yp, xp), 1, (255, 0, 0), -1) print "X: ", x print "Y: ", y # coefficients = poly.polyfit(x, y, 1) # print "Cof: ", coefficients # polynomial = np.poly1d(coefficients) # print "Poly: ", polynomial # print "Y: new", polynomial(x) vy, vx, cy, cx = cv2.fitLine(np.float32(points), cv2.DIST_L2, 0, 0.01, 0.01) cv2.line( self.__image, (int(cx - vx * 50), int(cy - vy * 50)), (int(cx + vx * 50), int(cy + vy * 50)), (0, 255, 255), )
def findLine(frame,cnt): rows,cols = frame.shape[:2] [vx,vy,x,y] = cv2.fitLine(cnt, cv2.cv.CV_DIST_L2,0,0.01,0.01) lefty = int((-x*vy/vx) + y) righty = int(((cols-x)*vy/vx)+y) cv2.line(frame,(cols-1,righty),(0,lefty),(0,255,0),2)#----# DISPLAYS LINE return [(cols-1,righty),(0,lefty)]
def getOffsetAngle(img, knuckles): [vx,vy,x,y] = cv2.fitLine(knuckles, cv2.DIST_L2,0,0.01,0.01) rows,cols = img.shape lefty = (-x * vy / vx) + y righty = ((cols - x) * vy / vx) +y height = righty - lefty hypot = math.hypot(cols - 1, height) return math.asin(height / hypot)
def get_avg_slope(img_, cont, index, drawline=False): rows, cols = img_.shape[:2] [vx, vy, x, y] = cv2.fitLine(cont[index], cv2.DIST_L2, 0, 0.01, 0.01) lefty = int((-x * vy / vx) + y) righty = int(((cols - x) * vy / vx) + y) slope = (lefty - righty) / (cols - 1) if drawline: cv2.line(img_, (cols - 1, righty), (0, lefty), (0, 255, 0), 2) return slope
def get_fitline(img, f_lines): rows, cols = img.shape[:2] output = cv2.fitLine(f_lines, cv2.DIST_L2, 0, 0.01, 0.01) vx, vy, x, y = output[0], output[1], output[2], output[3] x1, y1 = int(((img.shape[0] - 1) - y) / vy * vx + x), img.shape[0] - 1 x2, y2 = int(((img.shape[0] / 2 + 100) - y) / vy * vx + x), int(img.shape[0] / 2 + 100) result = [x1, y1, x2, y2] return result
def leastSquaresLine(self): # try to fit a least-squares trend line multiplier = 2000 dx, dy, x0, y0 = cv2.fitLine(self.points.numpyArray(), cv2.cv.CV_DIST_L2, 0, 0.01, 0.01) self.start = Point(int(x0 - dx*multiplier), int(y0 - dy*multiplier)) self.end = Point(int(x0 + dx*multiplier), int(y0 + dy*multiplier)) self.angle = self.calculateAngle(self.start, self.end)
def SetFitLine(self,cnt): vx,vy,x,y = cv2.fitLine(cnt[2],cv2.cv.CV_DIST_L2,0,0.01,0.01) lefty = int((-x*vy/vx) + y) righty = int(((cnt[2].shape[1]-x)*vy/vx)+y) self.lefY=lefty self.rigY=righty
def getStartingPoint2(cnts): i = 0 #gets the delta X and Y and finds the slope [dx, dy] = cv2.fitLine(filterCnts[i], cv2.DIST_L2, 0, 0.01, 0.01)[:2] m = dy / dx #the y axis is inverted so the slope is also inverted if m < 0: i = 1 return i
def __arrow_direction(self): linImg = (self.predImg == 2).astype(np.uint8) * 255 _, contours, _ = cv2.findContours(linImg, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE) if len(contours) > 0: contours = max( contours, key=lambda x: len(x)) # Si encuentra mas de un contorno if len(contours) < 100 or self.__limit(contours): return False caja = np.int0(cv2.boxPoints(cv2.fitEllipse(contours))) # Calculamos los puntos medios del rectangulo pm1 = (caja[3] + caja[0]) / 2 pm2 = (caja[2] + caja[1]) / 2 moments = cv2.moments(contours) x = int(moments['m10'] / moments['m00']) y = int(moments['m01'] / moments['m00']) punta = pm1 if self.distancia(pm1, (x, y)) < self.distancia( pm2, (x, y)) else pm2 [vx, vy, x, y] = cv2.fitLine(np.array([np.array(punta), np.array([x, y])]), cv2.DIST_L2, 0, 0.01, 0.01) lefty = int((-x * vy / vx) + y) righty = int(((self.width - x) * vy / vx) + y) k = (0 - y) / vy xtop = (k * vx) + x if math.isinf(xtop): upper = 99999999 else: upper = int(xtop) k = (self.height - y) / vy xlow = (k * vx) + x if math.isinf(xlow): lower = 99999999 else: lower = int(xlow) corte = [] if lefty >= 0 and lefty <= self.height - 1: corte.append([0, lefty]) if upper >= 0 and upper <= self.width - 1: corte.append([upper, 0]) if righty >= 0 and righty <= self.height - 1: corte.append([self.width - 1, righty]) if lower >= 0 and lower <= self.width - 1: corte.append([lower, self.height - 1]) if self.distancia(tuple(corte[0]), punta) < self.distancia( tuple(corte[0]), (x, y)): self.auxiliar = tuple(corte[0]) else: self.auxiliar = tuple(corte[1]) return True
def red_rope(frame, middle_earth): vidwidth, vidheight, channels = frame.shape hsv = cv2.cvtColor( frame, cv2.COLOR_BGR2HSV ) # define the lower (a) and upper(b) filter limits: HSV or BGR 0 - 255 a1 = 135 # was 130 a2 = 0 a3 = 0 b1 = 190 # H 0 - 180 likely conversions to HSV b2 = 150 # S 0 - 255 b3 = 150 # V 0 - 255 lower_color = np.array([a1, a2, a3]) # hsv hue sat value upper_color = np.array([b1, b2, b3]) mask = cv2.inRange(hsv, lower_color, upper_color) # find out color and display in black cv2.imshow('mask', mask) # res = cv2.bitwise_and(im, im, mask = mask) kernel = np.ones((15, 15), np.uint8) closing = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel) # inverted = cv2.bitwise_not(closing) # Invert floodfilled image thresh, contours, hierarchy = cv2.findContours( closing, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # find contoured objects hmin = 150 wmax = 200 for contour in contours: #for all contours detected [x, y, w, h] = cv2.boundingRect(contour) if h > hmin and w < wmax: # conditions for rope contour rows, cols = mask.shape[:2] [vx, vy, x, y] = cv2.fitLine(contour, cv2.DIST_L2, 0, 0.01, 0.01) # Now find two extreme points on the line (out of frame) rope_line_windowleft_y = int( (-x * vy / vx) + y) # pixels above y = 0 where line intersects frame edge rope_line_windowright_y = abs( int(((frame.shape[1] - x) * vy / vx) + y)) # pixels below y = 0 where line intersects frame edge total_line_height = rope_line_windowleft_y + rope_line_windowright_y red_line_base = frame.shape[1] - 1 target_y = middle_earth + 8 # arbirtray 8 simTri_base = int(target_y + rope_line_windowright_y) target_x = int(red_line_base / total_line_height * simTri_base) target_x = red_line_base - target_x cv2.line(frame, (x, y), (target_x, target_y), (0, 0, 100), 3) ship_x = x #output ship posn for later calcs ship_y = y else: continue return target_x, target_y, ship_x, ship_y
def _fit_line(bin_cuts): '''line fitting fits line to contour in every cut out and returns coordinates and length Parameters ---------- bin_cuts : list of np.Array of shape (w, h, 1) list of the shadow contours that were cropped out from binary mask Returns ------- line_xy : list of np.Array of shape (2, _) list of coordinates of approximated line for contour in every cut out line_lengths: list of float list of length of approximated line for contour in every cut out ''' i = 0 line_xy = [] line_lengths = [] for bin_cut in bin_cuts: # find contour in cut out image contours, hierarchy = cv2.findContours(bin_cut, 1, 2) cnt = contours[0] '''fit line to contour and get coordinates this part is taken from the documentation. It is not fully clear how it works. Other approaches did not work.''' rows, cols = bin_cut.shape[:2] [vx, vy, x, y] = cv2.fitLine(cnt, cv2.DIST_L2, 0, 0.01, 0.01) lefty = int((-x * vy / vx) + y) righty = int(((cols - x) * vy / vx) + y) # the code does not work for vx <= 0, it this is the case # no line is returned if vx > 0: # create black image with white line image_line = np.zeros((bin_cut.shape)) img_line = cv2.line(image_line, (cols - 1, righty), (0, lefty), (170, 255, 0), 2) # overlay line image and contour image img_sum = img_line + bin_cut # find pixels in line and add to list line_x, line_y = np.where(img_sum > 170) line_xy.append(np.array([line_x, line_y])) # find line length and add to list length = math.sqrt((line_x[-1] - line_x[0]) ** 2 + (line_y[-1] - line_y[0]) ** 2) line_lengths.append(length) else: print(f'No line found for contour on index {i}.') line_xy.append([[], []]) line_lengths.append(0) i += 1 return line_xy, line_lengths
def horizont_line_pipeline_verbose(self, image, model, img_w, img_h, average_n_frame, kernel_median_blur=50, predict_treshold=0.5, rho=2, theta=np.pi / 180, threshold=20, min_line_length=20, max_line_gap=5): or_image = image or_height, or_width, or_depth = or_image.shape image = self.inputNormalized(or_image, img_w, img_h) predict_segmentation = self.predict_segmentation(image, model) predict = self.median_blur(predict_segmentation, kernel_median_blur) predict = self.get_binary_image(predict, predict_treshold) predict = self.resize_image(predict, or_width, or_height) output = self.binary_edge_detection(predict) output = self.binary2gray(output) rho = rho # distance resolution in pixels of the Hough grid theta = theta # angular resolution in radians of the Hough grid threshold = threshold # minimum number of votes (intersections in Hough grid cell) min_line_length = min_line_length #minimum number f pixels making up a line max_line_gap = 5 # maximum gap in pixels between connectable line segments lines = self.hough_lines(output, rho, theta, threshold, min_line_length, max_line_gap) line_arr = np.squeeze(lines) points = self.Collect_points(line_arr) if (len(points) < 2): points = line_arr.reshape(lines.shape[0] * 2, 2) if (len(points) > 2): fit_line = cv2.fitLine(np.float32(points), cv2.DIST_HUBER, 1, 0.001, 0.001) #self.line.append(fit_line) #if len(self.line) > 10: # fit_line = self.smoothing(self.line, average_n_frame) pred_visual = predict_segmentation * 255 pred_visual = np.uint8( np.concatenate( (predict_segmentation, predict_segmentation, pred_visual), axis=2)) return fit_line, self.resize_image(predict_segmentation, or_width, or_height), self.resize_image( or_image, img_w, img_h), self.resize_image( pred_visual, img_w, img_h)
def test(data): global last_hsv_values original_image = bridge.imgmsg_to_cv2(data, desired_encoding="bgr8") img = cv2.cvtColor(original_image, cv2.COLOR_BGR2GRAY) # img = cv2.imread('/home/aditya/catkin_ws/src/image_masking/scripts/yellow_tape_good_lighting74.png',0) hsv = cv2.cvtColor(original_image, cv2.COLOR_BGR2HSV) #Otsu's Binarization on Grayscale to detect X,Y positions of line. blur = cv2.GaussianBlur(img, (5, 5), 0) ret3, th3 = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) im2, contours, hierarchy = cv2.findContours(th3, 1, 2) if len(contours) > 0: c = max(contours, key=cv2.contourArea) cnt = c M = cv2.moments(cnt) cx = int(M['m10'] / M['m00']) cy = int(M['m01'] / M['m00']) print("CX:" + str(cx) + " CY:" + str(cy)) print("Corresponding HSV values are: " + str(hsv[cy][cx])) # x and y values are reversed in HSV MATRIX. cv2.circle(img, (cx, cy), 10, (0, 0, 255), -1) rect = cv2.minAreaRect(cnt) box = cv2.boxPoints(rect) box = np.int0(box) cv2.drawContours(img, [box], 0, (0, 0, 255), 2) rows, cols = th3.shape[:2] [vx, vy, x, y] = cv2.fitLine(cnt, cv2.DIST_L2, 0, 0.01, 0.01) lefty = int((-x * vy / vx) + y) righty = int(((cols - x) * vy / vx) + y) print(str((cols - 1)) + "," + str(righty)) print(str(0) + " " + str(lefty)) cv2.line(img, (cols - 1, righty), (0, lefty), (0, 255, 0), 2) #cv2.imshow("th3",img) #cv2.imshow("th32",th3) #cv2.imshow("hsv",hsv) #cv2.waitKey(0) if ( hsv[cy][cx][0] > 34 or hsv[cy][cx][0] < 28 or ((abs(hsv[cy][cx][0] - last_hsv_values[0])) > 40) or hsv[cy][cx][2] < 250 ): #preferably here the HSV values for the desired color would go to filter out unwanted data. last_hsv_values = hsv[cy][cx] return np.array([0, 0, 0]) else: last_hsv_values = hsv[cy][cx] return hsv[cy][cx]
def fitline(arr): ret, thresh = cv2.threshold(arr, 127, 255, cv2.THRESH_BINARY) _, contours, _ = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) cnt = contours[0] [vx, vy, x, y] = cv2.fitLine(cnt, cv2.DIST_L2, 0, 0.01, 0.01) lefty = int((-x * vy / vx) + y) righty = int(((arr.shape[1] - x) * vy / vx) + y) cv2.line(arr, (arr.shape[1] - 1, righty), (0, lefty), 255, 2) return arr
def fit_line(cont_points): # print("cont_points:",cont_points) output = cv2.fitLine(cont_points, cv2.DIST_HUBER, 0, 0.01, 0.01) # 最小二乘法 # print("output:",output) k = output[1] / output[0] b = output[3] - k * output[2] # print("k: ",k) # print("b: ",b) return k, b
def _detect(thresh, cfg): """ use contours and fitline to detect line """ contours, hier = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) if contours is None: return [] return [ cv2.fitLine(cnt, cv2.cv.CV_DIST_L2, 0, 0.01, 0.01) for cnt in contours ]
def determine_tray_orientation(self, image): grey_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) mask = cv2.threshold(grey_image, 1, 255, cv2.THRESH_BINARY) mask = mask[1] kernel = np.ones((10, 10), np.uint8) dilation = cv2.dilate(mask, kernel, iterations=10) img, contours, hierarchy = cv2.findContours(dilation, 1, 2) max_contour = max(contours, key=cv2.contourArea) [vx, vy, x, y] = cv2.fitLine(max_contour, cv2.DIST_L2, 0, 0.01, 0.01) return np.sign(vx / vy)
def draw_lanes(left_lane_sa, right_lane_sa, frame): (vx_left, vy_left, x0_left, y0_left) = cv2.fitLine(left_lane_sa, cv2.DIST_L2, 0, 0.01, 0.01) (vx_right, vy_right, x0_right, y0_right) = cv2.fitLine(right_lane_sa, cv2.DIST_L2, 0, 0.01, 0.01) left_len = len(left_lane_sa) right_len = len(right_lane_sa) slope_left = vy_left / vx_left slope_right = vy_right / vx_right intercept_left = y0_left - (slope_left * x0_left) intercept_right = y0_right - (slope_right * x0_right) ysize = frame.shape[0] xsize = frame.shape[1] y_limit_low = int(0.95 * ysize) y_limit_high = int(0.65 * ysize) #Coordinates for point 1(Bottom Left) y_1 = ysize x_1 = int((y_1 - intercept_left) / slope_left) #Coordinates for point 2(Bottom Left) y_2 = y_limit_high x_2 = int((y_2 - intercept_left) / slope_left) #Coordinates for point 3(Bottom Left) y_3 = y_limit_high x_3 = int((y_3 - intercept_right) / slope_right) #Coordinates for point 4(Bottom Right) y_4 = ysize x_4 = int((y_4 - intercept_right) / slope_right) #Draw lines cv2.line(frame, (x_1, y_1), (x_2, y_2), (0, 255, 255), 3) cv2.line(frame, (x_3, y_3), (x_4, y_4), (0, 255, 255), 3) pts = np.array([[x_1, y_1], [x_2, y_2], [x_3, y_3], [x_4, y_4]]) mask_color = (255, 255, 0) frame_copy = frame.copy() cv2.fillPoly(frame_copy, np.int32([pts]), mask_color) opacity = 0.4 cv2.addWeighted(frame_copy, opacity, frame, 1 - opacity, 0, frame)
def main(): src_path = "test_images/ben_stroke_1.png" tag_path = "test_images/ben_stroke_1.png" src_img = cv2.imread(src_path, 0) tag_img = cv2.imread(tag_path, 0) _, src_img = cv2.threshold(src_img, 127, 255, cv2.THRESH_BINARY) _, tag_img = cv2.threshold(tag_img, 127, 255, cv2.THRESH_BINARY) src_img_rgb = cv2.cvtColor(src_img, cv2.COLOR_GRAY2RGB) tag_img_rgb = cv2.cvtColor(tag_img, cv2.COLOR_GRAY2RGB) _, src_contours, src_he = cv2.findContours(src_img, 1, 2) _, tag_contours, tag_he = cv2.findContours(tag_img, 1, 2) print(src_contours) src_cnt = src_contours[0] tag_cnt = tag_contours[0] rows, cols = src_img.shape [vx, vy, x, y] = cv2.fitLine(src_cnt, cv2.DIST_L2, 0, 0.01, 0.01) lefty = int((-x * vy / vx) + y) righty = int(((cols - x) * vy / vx) + y) cv2.line(src_img_rgb, (cols - 1, righty), (0, lefty), (0, 255, 0), 2) cv2.line(src_img_rgb, (cols - 1, lefty), (0, lefty), (0, 0, 255), 1) rows, cols = tag_img.shape [vx, vy, x, y] = cv2.fitLine(tag_cnt, cv2.DIST_L2, 0, 0.01, 0.01) lefty = int((-x * vy / vx) + y) righty = int(((cols - x) * vy / vx) + y) cv2.line(tag_img_rgb, (cols - 1, righty), (0, lefty), (0, 255, 0), 2) cv2.line(tag_img_rgb, (cols - 1, lefty), (0, lefty), (0, 0, 255), 1) src_img_rgb_ = addIntersectedFig(src_img_rgb) tag_img_rgb_ = addIntersectedFig(tag_img_rgb) cv2.imshow("src img", src_img_rgb_) cv2.imshow("tag img", tag_img_rgb_) cv2.waitKey(0) cv2.destroyAllWindows()
def isRight(self, contour, hsv): rows,cols = hsv.shape[:2] [vx,vy,x,y] = cv2.fitLine(contour, cv2.DIST_L2,0,0.01,0.01) lefty = int((-x*vy/vx) + y) righty = int(((cols-x)*vy/vx)+y) cv2.line(hsv,(cols-1,righty),(0,lefty),(0,255,0),2) slope = (vy)/(vx) if slope > 0: return True return False
def Cal_kb(self, data_line1): loc = data_line1.reshape(-1, 2) output = cv2.fitLine(loc, cv2.DIST_L2, 0, 0.01, 0.01) k = output[1] / output[0] k = list(k)[0] b = output[3] - k * output[2] b = list(b)[0] return output, k, b
def fit_line(contours, img, color=(0, 255, 0)): rows, cols = img.shape[:2] cnt = contours[0] [vx, vy, x, y] = cv2.fitLine(cnt, cv2.DIST_L2, 0, 0.01, 0.01) lefty = int((-x * vy / vx) + y) righty = int(((cols - x) * vy / vx) + y) angle = np.abs(np.arctan((lefty - righty) / (0 - (cols - 1)))) angle = min([angle, np.pi / 2 - angle]) * 180 / np.pi return img, angle
def getRect(self, im, cnt): m = [0, 0] if len(cnt): rows, cols = im.shape[:2] [vx, vy, x, y] = cv2.fitLine(cnt, cv2.DIST_L2, 0, 0.01, 0.01) m = [vx, vy] lefty = int((-x * vy / vx) + y) righty = int(((cols - x) * vy / vx) + y) im = cv2.line(im, (cols - 1, righty), (0, lefty), (0, 255, 0), 2) return m
def __analyze(group): global all_points points = [] for idx in group: points += __generate(*hashmap[idx], 10) _, radius = cv2.minEnclosingCircle(na(points)); w = radius * (math.pi/2) vx, vy, cx, cy = cv2.fitLine(na(points), cv2.DIST_L2, 0, 0.01, 0.01) # debug.color() all_points += points return [[int(cx-vx*w), int(cy-vy*w)], [int(cx+vx*w), int(cy+vy*w)]]
def filter_contours(self, contours, top_index, vp, img): """ Takes contours found by find_contours and filters out the contours that do not correspond to lane markings. This function filters as lane markings should converge towards the vanishing point top_index: index of contours with largest areas """ rows, cols = img.shape[:2] slopes = [] # list containing slope of remaining lines in image intercepts = [] # list of y-intercepts of remaining lines in image lane_ids = [] # indices of lines that do correspond to lanes # 1) For each line, find slope and intercept of line. for i in range(len(top_index)): [vx,vy,x,y] = cv.fitLine(contours[top_index[i]], cv.cv.CV_DIST_L2,0,0.01,0.01) # Slope m m = float(vy)/vx # y = m * x + b => b = y - m * x b = y - m * x slopes.append(m[0]) intercepts.append(b[0]) # 2) For each line check if y = m * vp_x + b = 0 # To check for y = 0, use threshold # TODO: justify thresh thresh = 25 # pixels y = m * vp[0] + b # (For debugging): show lines that are being filtered print y p1 = (0, int(intercepts[i])) p2 = (cols, int(slopes[i]*cols + intercepts[i])) # cv.line(img, p1, p2, (0, 200, 200), 5) # cv.imshow("img", img) # cv.waitKey(0) if abs(y) <= thresh: lane_ids.append(i) cv.circle(img, vp, 5, (100, 100, 0), 4) # 3) Draw only the lane markings for id in lane_ids: p1 = (0, int(intercepts[id])) p2 = (cols, int(slopes[id]*cols + intercepts[id])) cv.line(img, p1, p2, (0, 200, 200), 3) # cv.imshow("contours", img) # cv.waitKey(0) return True
def rotateFromPixels(self,image,cnt,tolerance=(10*math.pi)/180): """ Takes in contour information and rotates based on the line of best fit through contour points. I discovered that this could be done after getting the original box though the box may reduce the effect of large skews. This program also considers the minimum area rectangle in case a letter is actually skewed only stretched (skew not detectable from box). I'm guessing that these will not always be the same since a statistical best fit is not always the same as finding the absolute max and min points. *Required Parameters* :param image: the image to rotate :param cnt: the contour information *Optional Parameters* :param tolerance: the allowable tolerance (deviation from 0 degrees in radians) """ d90=(90*math.pi)/180 box=np.int0(cv2.boxPoints(cv2.minAreaRect(cnt))) x0,y0=box[0] x1,y1=box[1] print str(math.atan(float(y1-y0/x1-x0))) boxpheta=math.atan(float(y1-y0/x1-x0)) image2=image print "BoxPheta: "+str(boxpheta) if abs(boxpheta-d90) > tolerance: [vx,vy,x,y]=cv2.fitLine(cnt,cv2.DIST_L2,0,0.01,0.01) slope=-1*(vx/vy) #find the perpendicular slope to the given slope i=1 if vx[0] is 0 and vy[0] is 1: return image2 else: print "Slope Points: "+str(vx[0])+","+str(vy[0]) print "Slope: "+str(slope) pheta=math.atan(slope) print "Pheta: "+str(pheta) print "Pheta (degrees)"+str((pheta*180)/math.pi) i+=1 time.sleep(random.randint(2,4)) print "\n\n\n\n\n" if vx[0] >0: image2=ndimage.rotate(image2,(pheta*180)/math.pi,mode='nearest',cval=100) return image2
def fitting_line_thruObject(self): ##### fitting a line ########### try: rows, cols = self.image.shape[:2] [vx, vy, x, y] = cv2.fitLine(points=self.centerCordinates, distType=cv2.cv.CV_DIST_L2, param=0, reps=0.01, aeps=0.01) lefty = int((-x * vy / vx) + y) righty = int(((cols - x) * vy / vx) + y) cv2.line(self.image, (cols - 1, righty), (0, lefty), (255, 255, 255), 2) except: pass
def process(self, source0): """ Runs the pipeline and sets all outputs to new values. """ # Step Resize_Image0: self.__resize_image_input = source0 (self.resize_image_output) = self.__resize_image( self.__resize_image_input, self.__resize_image_width, self.__resize_image_height, self.__resize_image_interpolation) # Step Blur0: self.__blur_input = self.resize_image_output (self.blur_output) = self.__blur(self.__blur_input, self.__blur_type, self.__blur_radius) # Step HSV_Threshold0: self.__hsv_threshold_input = self.blur_output (self.hsv_threshold_output) = self.__hsv_threshold( self.__hsv_threshold_input, self.__hsv_threshold_hue, self.__hsv_threshold_saturation, self.__hsv_threshold_value) # Step Mask0: self.__mask_input = self.resize_image_output self.__mask_mask = self.hsv_threshold_output (self.mask_output) = self.__mask(self.__mask_input, self.__mask_mask) image = cv2.cvtColor(self.mask_output, cv2.COLOR_BGR2GRAY) thresh = 127 image = cv2.threshold(image, thresh, 255, cv2.THRESH_BINARY)[1] rows, cols = image.shape M = cv2.getRotationMatrix2D((cols / 2, rows / 2), 90, 1) image = cv2.warpAffine(image, M, (cols, rows)) points = numpy.argwhere(image == 255) if len(points) > 0: [vx, vy, x, y] = cv2.fitLine(points, cv2.DIST_L2, 0, 0.01, 0.01) else: [vx, vy, x, y] = [0, 0, 0, 0] #publish results to network tables sd = tableInstance.getTable("LineData") print("Is table connected: " + str(tableInstance.isConnected()) + "\n\n\n") sd.putNumber("vx", vx) sd.putNumber("vy", vy) sd.putNumber("x", x) sd.putNumber("y", y) NetworkTables.shutdown()
def fitline(data): nz = np.nonzero(data) nzt = np.transpose(np.asarray(nz)) nzta = np.array(nzt) # have refline or not if len(nzta) < 2: return 0, 0, 0, 0 # Height is X axis, and Width is Y axis for Img [vh, vw, h, w] = cv.fitLine(nzta, cv.DIST_HUBER, 0, 0.01, 0.01) return vh, vw, h, w
def image_callback(self, data): try: cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8") print "done" except CvBridgeError as e: print(e) print "not_done" hsv_img = cv2.cvtColor(cv_image, cv2.COLOR_BGR2HSV) sho = cv2.namedWindow('Show', cv2.WINDOW_NORMAL) cv2.imshow('Show', cv_image) #thresholding frame_threshed = cv2.inRange(hsv_img, self.COLOR_MIN, self.COLOR_MAX) #ret,thresh = cv2.threshold(frame_threshed, 127,255,0) contours, hierarchy = cv2.findContours(frame_threshed, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) #v2.imshow("Show",thresh) print len(contours) # Find the index of the largest contour areas = [cv2.contourArea(c) for c in contours] max_index = np.argmax(areas) cnt = contours[max_index] #M = cv2.moments(cnt) # print M #cx = int(M['m10']/M['m00']) #cy = int(M['m01']/M['m00']) x, y, w, h = cv2.boundingRect(cnt) cv2.rectangle(cv_image, (x, y), (x + w, y + h), (0, 255, 0), 10) rows, cols = cv_image.shape[:2] [vx, vy, x, y] = cv2.fitLine(cnt, cv2.cv.CV_DIST_L2, 0, 0.01, 0.01) lefty = int((-x * vy / vx) + y) righty = int(((cols - x) * vy / vx) + y) cv_image = cv2.line(cv_image, (cols - 1, righty), (0, lefty), (0, 255, 0), 1) rect = cv2.minAreaRect(cnt)[-1] print rect self.angle = rect if (-90 < self.angle < 0): self.motor_direction = self.COUNTER_CLOCKWISE if (-2 < self.angle < 2): self.motor_direction = self.STRAIGHT elif 90 > self.angle > 0: self.motor_direction = self.CLOCKWISE self.pub.publish(self.motor_direction) cv2.waitKey(3)
def get_contour_line_on_image(contour, image): rows, cols = image.shape[:2] [vx, vy, x, y] = cv2.fitLine(contour, cv2.DIST_L2, 0, 0.01, 0.01) # First point x1 = 0 y1 = int((-x * vy / vx) + y) # Second point x2 = cols - 1 y2 = int(((cols - x) * vy / vx) + y) return x1, y1, x2, y2
def fitLine_ransac(pts, leftx=0, rightx=PLATE_SIZE_BIG_WIDTH, zero_add=0): if len(pts) >= 2: if len(pts) == 2: avg = (pts[0][1] + pts[1][1]) / 2 pts[0][1] = pts[1][1] = avg [vx, vy, x, y] = cv2.fitLine(pts, cv2.DIST_HUBER, 0, 0.01, 0.01) lefty = int(((leftx - x) * vy / vx) + y) righty = int(((rightx - x) * vy / vx) + y) return lefty + 30 + zero_add, righty + 30 + zero_add return 0, 0
def fit_line(fit_to, save_to): """Fits the line to the set of points Arguments: fit_to {np.array} -- set of points save_to {dict} -- result of the fitting is saved to this line """ vx, vy, x, y = cv2.fitLine(fit_to, cv2.DIST_L2, 0, 0.01, 0.01) save_to["point"] = (int(x), int(y)) save_to["vx"] = float(vx) save_to["vy"] = float(vy)
def line(image, color_img, contours): rows, cols = image.shape[:2] [vx, vy, x, y] = cv.fitLine(contours[0], cv.DIST_L2, 0, 0.01, 0.01) lefty = int((-x * vy / vx) + y) righty = int((cols - x) * vy / vx + y) cv.line(color_img, (cols - 1, righty), (0, lefty), (0, 255, 0), 2) return [lefty, righty]
def get_fitline(self, img, f_line): #대표 선 구하기 lines = np.squeeze(f_line) lines = lines.reshape(lines.shape[0] * 2, 2) rows, cols = img.shape[:2] output = cv2.fitLine(lines, cv2.DIST_L2, 0, 0.01, 0.01) vx, vy, x, y = output[0], output[1], output[2], output[3] x1, y1 = int(((img.shape[0] - 1) - y) / vy * vx + x), img.shape[0] - 1 x2, y2 = int(((img.shape[0] / 2 + 100) - y) / vy * vx + x), int(img.shape[0] / 2 + 100) result = [x1, y1, x2, y2] return result
def getFitLine(self, frame, lines) : r,c = frame.shape[:2] default_line = cv2.fitLine(lines,cv2.DIST_L2,0,0.01,0.01) tx0,ty0,tx1,ty1 = default_line #print(' ', tx0,' ', ty0,' ', tx1,' ',ty1) x0 = int(((frame.shape[0]-1)-ty1)/ty0*tx0 + tx1) y0 = frame.shape[0]-1 x1 = int(((frame.shape[0]/2+100)-ty1)/ty0*tx0 + tx1) y1 = int(frame.shape[0]/2+100) return [x0,y0,x1,y1]
def fitLine(points, row, col): [vx, vy, x, y] = cv2.fitLine(points, cv2.DIST_L2, 0, 0.01, 0.01) left = Point(0, int(-x * vy / vx + y)) right = Point(col - 1, int((col - 1 - x) * vy / vx + y)) top = Point(int(-y * vx / vy + x), 0) bot = Point(int((row - 1 - y) * vx / vy + x), row - 1) points = [left, right, top, bot] points.sort(key=lambda p: (p.x - x)**2 + (p.y - y)**2) return points[0], points[1], [vx, vy, x, y]
def color_contours(self, blob_img, contours): """ Return a colored image where the regions within certain the contours is colored in. :param blob_image: :return: """ labeled_img = np.zeros(blob_img.shape + (3, ), np.uint8) colors = ((0,0,255),(0,255,0),(255,0,0),(0,255,255),(255,0,255), (255, 255, 0)) pnts_list = [] mask_list = [] for ind, contour in enumerate(contours): mask = np.zeros(blob_img.shape, np.uint8) cv2.drawContours(mask, [contour], 0, 255, -1, 8) pixel_points = cv2.findNonZero(mask)#(x,y) labeled_img[mask == 255] = colors[ind] pnts_list.append(pixel_points) mask_list.append(mask) k = 0 angles = [] for cnt in contours: if len(cnt) < 10: #don't care about tiny contours # this should have already been protected for in the # large_contour code, but that is technically area angles.append(0) continue pixel_points = pnts_list[k] M = cv2.moments(cnt)#expects to get a contour - uses Green's theorem #center of blob cx = int(M['m10']/M['m00']) cy = int(M['m01']/M['m00']) #ellipsoid outline of blob ellipse = cv2.fitEllipse(cnt) (x, y), (MA, ma), angle = cv2.fitEllipse(pixel_points)#yet another way to get the angle angles.append(angle) #line fitting, THIS WAS SLOWING ME DOWN #DIST_L1 = 1: |x1-x2| + |y1-y2| */, DIST_L2 = 2: euclidean distance, DIST_C = : max(|x1-x2|,|y1-y2|) [vx, vy, x, y] = cv2.fitLine(pixel_points, 1, 0, 0.01, 0.01) pt1 = (np.array((x, y)) + 20*np.array((vx, vy))).astype('int32') pt2 = (np.array((x, y)) - 20*np.array((vx, vy))).astype('int32') cv2.line(labeled_img, tuple(pt1), tuple(pt2), (0, 128, 128), 2, 8) k += 1 return labeled_img, angles
def _get_point_normal_pixel_coordinates(self, shape, point_index): """ Get the coordinates of pixels lying on the normal of the point :param shape: :param point_index: :return: """ point = shape.get_point(point_index) neighborhood = shape.get_neighborhood(point_index, self._normal_neighborhood) line = cv2.fitLine(neighborhood, cv2.DIST_L2, 0, 0.01, 0.01) slope = line[0:2] / math.sqrt(np.sum(line[0:2] ** 2)) return [[int(point[1] + (incr * slope[0]) + 0.5), int(point[0] - (incr * slope[1]) + 0.5)] for incr in range(-self._number_of_pixels, self._number_of_pixels + 1)]
def find_lines(self, contours, image): lines = [] for contour in contours: approx = cv2.approxPolyDP(contour, 0, False) area = np.abs(cv2.contourArea(contour)) if self.area_min.get() < area < self.area_max.get(): line_values = cv2.fitLine(approx, cv.CV_DIST_L2, 0, 0.01, 0.01) rect = cv2.boundingRect(approx) t = math.sqrt((rect[2] ** 2 + rect[3] ** 2) / 2.0) lines.append((line_values, t)) cv2.drawContours(image, contour, -1, (255, 255, 0)) return lines
def ProcessFrame(frame): out = obj([False, 0, 0, 0]) pRed = frame[:, :, 2] frame = norm(frame) red = frame[:,:,2] debugFrame("red", red) (row, col, pages) = frame.shape maxArea = (row * col)/3 minArea = 200 red = cv2.medianBlur(red, ksize = 3) ret, thresh = cv2.threshold(red, 120, 255, cv2.THRESH_BINARY) debugFrame("threshOg", thresh) kernel = np.ones((7,7),np.uint8) thresh = cv2.erode(thresh,kernel, iterations = 2) debugFrame("thresh", thresh) contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) possiblePoles = [] if contours != None: for cont in contours: if len(cont) < 3: continue; (center, (w, h), ang) = cv2.minAreaRect(cont) area = w * h aspectRatio = 0 if w != 0: aspectRatio = h / w if aspectRatio < 1 and aspectRatio != 0: aspectRatio = 1/aspectRatio if area > 1000 and aspectRatio > 3 and aspectRatio < 13: angp = abs(ang) angp = abs(angp - round((angp/90.0)) * 90) loc = (int(center[0]), int(center[1])) cv2.drawContours(frame, [cont], -1, (0,0, 0), 3) [vx,vy,x,y] = cv2.fitLine(cont, 2,0,0.01,0.01) if vx > .01: lefty = int((-x*vy/vx) + y) righty = int(((col-x)*vy/vx)+y) cv2.line(frame,(col-1,righty),(0,lefty),(0,255,0),2) angm = math.degrees(math.atan2(vy,vx)) angM = angm - round((angm/90.0)) * 90 stringOut = "angP %.2f, asp %.2f" % (angM, aspectRatio) cv2.putText(frame, stringOut, loc, cv2.FONT_HERSHEY_SIMPLEX, .5, 255) out = obj([True, angM, center[0], center[1]]) out.draw(frame) debugFrame("out", frame) return out
def merge_edges(self, edges): points = [] for edge in edges: points.append([edge.x1, edge.y1]) points.append([edge.x2, edge.y2]) points = np.reshape(points, (len(edges)*2,2)) [vx, vy, x, y] = cv2.fitLine(points, cv2.cv.CV_DIST_HUBER, 0, 0.01, 0.01) lefty = int((-x*vy/vx) + y) righty = int(((self.im.shape[1]-x)*vy/vx)+y) cv2.line(self.im, (self.im.shape[1]-1, righty), (0, lefty), (0, 0, 255), 1) return vx, vy, x, y
def drawLine(self,best_cnt, frame): pass vx,vy,x,y = cv2.fitLine(best_cnt,cv2.cv.CV_DIST_L2, 0, 0.01, 0.01) # Averageing self.xAv.append(vx) self.yAv.append(vy) del self.xAv[0] del self.yAv[0] vx = sum(self.xAv)/self.binsize vy = sum(self.yAv)/self.binsize x0 = x+vx*20 y0 = y+vy*20 x1 = x-vx*20 y1 = y-vy*20 cv2.line(frame,(x1,y1),(x0,y0), (255,255,100),2)
def fit_line(segment): pts = np.nonzero(segment.mask) pts = np.array(pts).T pts_len = pts.shape[0] pts = pts.reshape((pts_len, 1, 3)) line = cv2.fitLine(pts.astype("float32"), 1,0, 0.01, 0.01) line = [x[0] for x in line] return line
def getLine(self, points, frame, color=(0, 0, 255)): if len(points) > 0: upperline = cv2.fitLine(points, 1, 0, 0.01, 0.01) # shim to prevent divide by zero upperline[0] = max(upperline[0], 0.0001) m = (upperline[1]/upperline[0]) b = (upperline[3]-m*upperline[2]) if self.debug: pt1 = (0, b + self.HEIGHT * self.CAMERA_CUTOFF) pt2 = (self.WIDTH,m*self.WIDTH + b + self.HEIGHT * self.CAMERA_CUTOFF) cv2.line(frame, pt1, pt2, color) return m[0], b[0] else: return 0, 0
def get_data(image,blur_val,thresh_val): """ Stores information about the different contour clusters of an image into a dictionary for future access. :argument image: Image to be analyzed. :type image: numpy.ndarray :argument blur_val: Size of the averaged pixel matrix used to blur the image before binarization. Used to generate the contour clusters. :type blur_val: int (must be positive and odd) :argument thresh_val: Minimum brightness a pixel must be to be binarized/stored as 1/White. Used to generate the contour clusters. :type thresh_val: int (between 0 and 255) :return: Dictionary of data gathered from the contour clusters of image. :rtype: dict """ contours = get_contours(image, blur_val, thresh_val) data = [] for contour in contours: current_roi = {} moments = cv2.moments(contour) centroid_x = 0 centroid_y = 0 try: centroid_x = int(moments['m10'] / moments['m00']) centroid_y = int(moments['m01'] / moments['m00']) except ZeroDivisionError: pass current_roi['Centroid'] = (centroid_x,centroid_y) [vx, vy, x, y] = cv2.fitLine(contour, cv2.DIST_L2, 0, 0.01, 0.01) current_roi['Vector'] = {'vx':vx[0],'vy':vy[0],'x':x[0],'y':y[0]} area = cv2.contourArea(contour) current_roi['Area'] = area perimeter = cv2.arcLength(contour, True) current_roi['ApproximatePerimeter'] = perimeter MA = 0 ma = 0 angle = 0 if len(contour) > 5: try: (x, y), (MA, ma), angle = cv2.fitEllipse(contour) except cv2.error: pass current_roi['Axes'] = {'Major Axis':MA,'Minor Axis':ma} current_roi['Direction'] = angle data.append(current_roi) return data
def update(_=None): noise = cv2.getTrackbarPos('noise', 'fit line') n = cv2.getTrackbarPos('point n', 'fit line') r = cv2.getTrackbarPos('outlier %', 'fit line') / 100.0 outn = int(n*r) p0, p1 = (90, 80), (w-90, h-80) img = np.zeros((h, w, 3), np.uint8) cv2.line(img, toint(p0), toint(p1), (0, 255, 0)) if n > 0: line_points = sample_line(p0, p1, n-outn, noise) outliers = np.random.rand(outn, 2) * (w, h) points = np.vstack([line_points, outliers]) for p in line_points: cv2.circle(img, toint(p), 2, (255, 255, 255), -1) for p in outliers: cv2.circle(img, toint(p), 2, (64, 64, 255), -1) func = getattr(cv2, cur_func_name) vx, vy, cx, cy = cv2.fitLine(np.float32(points), func, 0, 0.01, 0.01) cv2.line(img, (int(cx-vx*w), int(cy-vy*w)), (int(cx+vx*w), int(cy+vy*w)), (0, 0, 255)) draw_str(img, (20, 20), cur_func_name) cv2.imshow('fit line', img)