def ProcessFrame(frame): out = obj([False, 0, 0, 0]) frameOut = np.copy(frame) frame = norm(frame) m = cv2.mean(frame) red = dist(frame, [m[0], m[1], 255]) 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, np.mean(red) - max(np.std(red), 10) * 2.65, 255, cv2.THRESH_BINARY_INV) 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) 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 ang += 90 else: aspectRatio = 1 #caluclating solidity contArea = cv2.contourArea(cont) if contArea < .1: conArea = 1.0 if area == 0: area = 1 solidity = contArea / (1.0 * area) loc = (int(center[0]), int(center[1])) stringOut = "%f" % (solidity) #cv2.putText(frameOut, stringOut, loc, cv2.FONT_HERSHEY_SIMPLEX, .5, 255) if area > 1500 and aspectRatio > 3 and aspectRatio < 13 and solidity > .8: angp = -1 * ang #angp = angp - round((angp/180.0)) * 180 stringOut += ", ang: %d" % (angp) cv2.drawContours(frameOut, [cont], -1, (0, 0, 0), 3) out = obj([True, angp, center[0], center[1]]) frameOut = out.draw(frameOut) cv2.putText(frameOut, stringOut, loc, cv2.FONT_HERSHEY_SIMPLEX, .5, 255) print stringOut debugFrame("out", frameOut) return out
def ProcessFrame(frame): out = obj() frameOut = frame.copy() frame = norm(frame) mean, std = cv2.meanStdDev(frame) r = dist(frame, (mean[0], mean[1], mean[2])) mean, std = cv2.meanStdDev(r) print "m: %d, std %d" % (mean, std) #r = frame[:, :, 2] r = cv2.GaussianBlur(r, (9, 9), 0) debugFrame("ChannelOfInterest", r) edges = cv2.Canny(r, std * 3.5, 1.2* std) debugFrame("edges", edges) lines = cv2.HoughLinesP(edges, 4, math.pi/180, 200, minLineLength = 100, maxLineGap = 50) if isinstance(lines, list): print "numLines: %d" % len(lines[0]) for line in lines[0]: p1 = (line[0], line[1]) p2 = (line[2], line[3]) dx = p1[0] - p2[0] dy = abs(p1[1] - p2[1]) theta = math.atan2(dy, dx) if abs(theta - math.pi/2) < 10 *math.pi/180: cv2.line(frameOut, p1, p2, (255, 0, 255), 5) """ Below is the param info for HoughCircles image is the imaged being looked at by the function method cv2.CV_HOUGH_GRADIENT is the only method available dp the size of accumulator inverse relative to input image, dp = 2 means accumulator is half dim of input image minDist minimum distance between detected circles, too small and mult neighbor circ founds, big and neighbor circ counted as same param1 bigger value input into canny, unsure why it is useful therefore not using param2 vote threshold minRadius min Radius of circle to look for maxRadius max Radius of circle to look for """ maxrad = 300 minrad = 10 step = 50 for radius in range(minrad + step, maxrad + 1, step): circles = cv2.HoughCircles(image = r, method = cv2.cv.CV_HOUGH_GRADIENT, dp = .5, minDist = radius * 2, param2 = int((2 * radius * math.pi)/15), minRadius = radius - step, maxRadius = radius) msg = "minRadius: %d, maxRadius %d" % (radius - step, radius) if type(circles) != type(None): print msg + " found: %d" % (len(circles)) for circ in circles[0,:]: out.append(circ) out.draw(frameOut) else: print msg + " no circ found" frameOut = out.draw(frameOut) debugFrame("houghProb", frameOut) print "-------------------------------" return out
def ProcessFrame(frame): print("called") out = obj() frameOut = frame.copy() HEIGHT, WIDTH, _ = frame.shape contImg = np.zeros((HEIGHT, WIDTH, 3), np.uint8) frame = norm(frame) mean, std = cv2.meanStdDev(frame) r = dist(frame, (mean[0], mean[1], mean[2])) mean, std = cv2.meanStdDev(r) print "m: %d, std %d" % (mean, std) #r = frame[:, :, 2] r = cv2.GaussianBlur(r, (9, 9), 0) debugFrame("red", r) if std > 6: edges = cv2.Canny(r, std * 1.8, std * 1.2) else: edges = cv2.Canny(r, 30, 20) debugFrame("edges", edges) lines = cv2.HoughLinesP(edges, 4, math.pi / 180, 200, minLineLength=100, maxLineGap=50) if isinstance(lines, list): print "numLines: %d" % len(lines[0]) for line in lines[0]: p1 = (line[0], line[1]) p2 = (line[2], line[3]) dx = p1[0] - p2[0] dy = abs(p1[1] - p2[1]) theta = math.atan2(dy, dx) if abs(theta - math.pi / 2) < 10 * math.pi / 180: cv2.line(frameOut, p1, p2, (255, 0, 255), 5) contours, _ = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) dice = [] for i in range(len(contours)): area = cv2.contourArea(contours[i]) if area < WIDTH * HEIGHT / 2: cv2.drawContours(contImg, contours, i, (255, 255, 255), 5) x, y, w, h = cv2.boundingRect(contours[i]) if w * h > 700 and h != 0 and w / h < 2 and w / h > 1 / 2: cv2.rectangle(frameOut, (x, y), (x + w, y + h), (0, 0, 255), 2) dice.append([x + w / 2, y + h / 2, (w + h) / 2]) debugFrame("contours", contImg) print "Contours: ", len(contours) if (len(dice) >= 2): for die in dice: out.append(die) frameOut = out.draw(frameOut) debugFrame("houghProb", frameOut) print "-------------------------------" return out
def ProcessFrame(frame): out = obj([False, 0, 0]) frameOut = frame.copy() frame = norm(frame) mean, std = cv2.meanStdDev(frame) r = dist(frame, (mean[0], mean[1], mean[2])) mean, std = cv2.meanStdDev(r) print "m: %d, std %d" % (mean, std) #r = frame[:, :, 2] r = cv2.GaussianBlur(r, (9, 9), 0) debugFrame("ChannelOfInterest", r) edges = cv2.Canny(r, std * 3.5, 1.2* std) debugFrame("edges", edges) lines = cv2.HoughLinesP(edges, 4, math.pi/180, 200, minLineLength = 100, maxLineGap = 50) if lines != None: print "numLines: %d" % len(lines[0]) for line in lines[0]: p1 = (line[0], line[1]) p2 = (line[2], line[3]) dx = p1[0] - p2[0] dy = abs(p1[1] - p2[1]) theta = math.atan2(dy, dx) if abs(theta - math.pi/2) < 10 *math.pi/180: cv2.line(frameOut, p1, p2, (255, 0, 255), 5) """ Below is the param info for HoughCircles image is the imaged being looked at by the function method cv2.CV_HOUGH_GRADIENT is the only method available dp the size of accumulator inverse relative to input image, dp = 2 means accumulator is half dim of input image minDist minimum distance between detected circles, too small and mult neighbor circ founds, big and neighbor circ counted as same param1 bigger value input into canny, unsure why it is useful therefore not using param2 vote threshold minRadius min Radius of circle to look for maxRadius max Radius of circle to look for """ maxrad = 300 minrad = 10 step = 50 for radius in range(minrad + step, maxrad + 1, step): circles = cv2.HoughCircles(image = r, method = cv2.cv.CV_HOUGH_GRADIENT, dp = .5, minDist = radius * 2, param2 = int((2 * radius * math.pi)/20), minRadius = radius - step, maxRadius = radius) msg = "minRadius: %d, maxRadius %d" % (radius - step, radius) if circles != None: print msg + " found: %d" % (len(circles)) for circ in circles[0,:]: cv2.circle(frameOut, (int(circ[0]), int(circ[1])), circ[2], (0, 255, 255), 2) cv2.circle(frameOut, (int(circ[0]), int(circ[1])), 2, (0, 0, 255), 2) else: print msg + " no circ found" frameOut = out.draw(frameOut) debugFrame("houghProb", frameOut) print "-------------------------------" return out.dict()
def ProcessFrame(frame): out = obj([False, 0, 0, 0]) frameOut = np.copy(frame) frame = norm(frame) m = cv2.mean(frame) red = dist(frame, [m[0], m[1], 255]) 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, np.mean(red) - max(np.std(red), 10) * 2.65, 255, cv2.THRESH_BINARY_INV) 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) 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 ang+=90 else: aspectRatio = 1 #caluclating solidity contArea = cv2.contourArea(cont) if contArea < .1: conArea = 1.0 if area == 0: area = 1 solidity = contArea / (1.0 * area) loc = (int(center[0]), int(center[1])) stringOut = "%f" % (solidity) #cv2.putText(frameOut, stringOut, loc, cv2.FONT_HERSHEY_SIMPLEX, .5, 255) if area > 1500 and aspectRatio > 3 and aspectRatio < 13 and solidity > .8: angp = -1 * ang #angp = angp - round((angp/180.0)) * 180 stringOut += ", ang: %d" % (angp) cv2.drawContours(frameOut, [cont], -1, (0,0, 0), 3) out = obj([True, angp, center[0], center[1]]) frameOut = out.draw(frameOut) cv2.putText(frameOut, stringOut, loc, cv2.FONT_HERSHEY_SIMPLEX, .5, 255) print stringOut debugFrame("out", frameOut) return out
def ProcessFrame(frame): print("called") out = obj() frameOut = frame.copy() HEIGHT,WIDTH,_ = frame.shape contImg = np.zeros((HEIGHT,WIDTH,3), np.uint8) frame = norm(frame) mean, std = cv2.meanStdDev(frame) r = dist(frame, (mean[0], mean[1], mean[2])) mean, std = cv2.meanStdDev(r) print "m: %d, std %d" % (mean, std) #r = frame[:, :, 2] r = cv2.GaussianBlur(r, (9, 9), 0) debugFrame("red", r) if std > 6: edges = cv2.Canny(r, std * 1.8 , std * 1.2) else: edges = cv2.Canny(r, 30 , 20) debugFrame("edges", edges) lines = cv2.HoughLinesP(edges, 4, math.pi/180, 200, minLineLength = 100, maxLineGap = 50) if isinstance(lines, list): print "numLines: %d" % len(lines[0]) for line in lines[0]: p1 = (line[0], line[1]) p2 = (line[2], line[3]) dx = p1[0] - p2[0] dy = abs(p1[1] - p2[1]) theta = math.atan2(dy, dx) if abs(theta - math.pi/2) < 10 *math.pi/180: cv2.line(frameOut, p1, p2, (255, 0, 255), 5) contours, _ = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) dice = [] for i in range(len(contours)): area = cv2.contourArea(contours[i]) if area < WIDTH * HEIGHT / 2: cv2.drawContours(contImg, contours, i, (255, 255, 255), 5) x,y,w,h = cv2.boundingRect(contours[i]) if w * h > 700 and h != 0 and w/h < 2 and w/h > 1/2: cv2.rectangle(frameOut,(x,y),(x+w,y+h),(0,0,255),2) dice.append([x + w/2, y + h/2, (w+h) / 2]) debugFrame("contours", contImg) print "Contours: ", len(contours) if(len(dice) >= 2): for die in dice: out.append(die) frameOut = out.draw(frameOut) debugFrame("houghProb", frameOut) print "-------------------------------" return out
def ProcessFrame(frame): out = obj([False, 0, 0]) frameOut = frame.copy() frame = norm(frame) mean, std = cv2.meanStdDev(frame) r = dist(frame, (mean[0], mean[1], 255)) r = cv2.cvtColor(frameOut, cv2.COLOR_BGR2GRAY) mean, std = cv2.meanStdDev(r) print "m: %d, std %d" % (mean, std) r = frame[:, :, 2] debugFrame("red", r) r = cv2.GaussianBlur(r, (7, 7), 0) edges = cv2.Canny(r, std * 2.0, 1.3 * std) debugFrame("edges", edges) lines = cv2.HoughLines(edges, 3, math.pi / 180, 110) poles = [] if lines != None: print "numLines: %d" % len(lines[0]) for line in lines[0]: r = line[0] theta = line[1] if (abs(theta - round((theta / math.pi)) * math.pi) < 3.0 * math.pi / 180.0): a = math.cos(theta) b = math.sin(theta) x0 = a * r y0 = b * r pt1 = (int(x0 - 100 * b), int(y0 + 100 * a)) pt2 = (int(x0 + 100 * b), int(y0 - 100 * a)) poles.append(((x0, y0), pt1, pt2)) cv2.line(frameOut, pt1, pt2, (255, 0, 255), 5) #filtering out the matching poles poles = sorted(poles, key=sortPoles) if len(poles) > 0: gatePoles = [poles[0]] for pole in poles: if abs(pole[0][0] - gatePoles[-1][0][0]) > 80: gatePoles.append(pole) for pole in gatePoles: cv2.line(frameOut, pole[1], pole[2], (0, 0, 255), 10) if len(gatePoles) == 2: out = obj([True, gatePoles[0][0][0], gatePoles[1][0][0]]) print "len Poles: %d, len gatePoles: %d" % (len(poles), len(gatePoles)) frameOut = out.draw(frameOut) debugFrame("houghReg", frameOut) print "-------------------------------" return out.dict()
def ProcessFrame(frame): out = obj([False, 0, 0]) frameOut = frame.copy() frame = norm(frame) mean, std = cv2.meanStdDev(frame) r = dist(frame, (mean[0], mean[1], 255)) mean, std = cv2.meanStdDev(r) print "m: %d, std %d" % (mean, std) #r = frame[:, :, 2] r = cv2.GaussianBlur(r, (9, 9), 0) debugFrame("red", r) edges = cv2.Canny(r, std * 1.8, 1.2 * std) debugFrame("edges", edges) lines = cv2.HoughLinesP(edges, 4, math.pi / 180, 145, minLineLength=200, maxLineGap=80) poles = [] if lines != None: print "numLines: %d" % len(lines[0]) for line in lines[0]: p1 = (line[0], line[1]) p2 = (line[2], line[3]) dx = p1[0] - p2[0] dy = abs(p1[1] - p2[1]) theta = math.atan2(dy, dx) if abs(theta - math.pi / 2) < 10 * math.pi / 180: cv2.line(frameOut, p1, p2, (255, 0, 255), 5) poles.append((p1, p2)) #filtering out the matching poles poles = sorted(poles, key=sortPoles) if len(poles) > 0: gatePoles = [poles[0]] for pole in poles: if abs(pole[0][0] - gatePoles[-1][0][0]) > 80: gatePoles.append(pole) for pole in gatePoles: cv2.line(frameOut, pole[0], pole[1], (0, 0, 255), 10) if len(gatePoles) == 2: out = obj([True, gatePoles[0][0][0], gatePoles[1][0][0]]) print "len Poles: %d, len gatePoles: %d" % (len(poles), len(gatePoles)) frameOut = out.draw(frameOut) debugFrame("houghProb", frameOut) print "-------------------------------" return out.dict()
def ProcessFrame(frame): out = obj([False, 0, 0]) frameOut = frame.copy() frame = norm(frame) mean, std = cv2.meanStdDev(frame) print "r mean: %d" % (mean[2]) r = dist(frame, (mean[0], mean[1], max(mean[2], 80))) mean, std = cv2.meanStdDev(r) print "m: %d, std %d" % (mean, std) #r = frame[:, :, 2] r = cv2.GaussianBlur(r, (9, 9), 0) debugFrame("red", r) if std > 6: edges = cv2.Canny(r, std * 2.0, std * 1.1) else: edges = cv2.Canny(r, 30 , 20) debugFrame("edges", edges) contours, _ = cv2.findContours(r, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) possiblePoles = [] for cont in contours: cv2.drawContours(frame, [cont], -1, (0, 0, 255), 3) (center, (w, h), ang) = cv2.minAreaRect(cont) area = w * h if w > 0: aspectRatio = h / w if aspectRatio < 1 and aspectRatio != 0: aspectRatio = 1/aspectRatio ang+=90 else: aspectRation = 20 angp = abs(ang) angp = abs(angp - round((angp/180.0)) * 180) stringOut = "%d %d %d" % (angp, area, aspectRatio) cv2.putText(frameOut, stringOut, (int(center[0]), int(center[1])), cv2.FONT_HERSHEY_SIMPLEX, .5, 255) if (angp < 10 or angp > 170) and area > minArea and area < maxArea and abs(aspectRatio) <= 2: possiblePoles.append((cont, center)) possiblePoles = sorted(possiblePoles, key = sortPoles) for pole in possiblePoles: cv2.drawContours(frameOut, [pole[0]], -1, (0, 0, 255), 3) (center, (w, h), ang) = cv2.minAreaRect(pole[0]) aspectRatio = h / w if aspectRatio < 1: ang+=90 angp = abs(ang) angp = abs(angp - round((angp/180)) * 180) area = h * w stringOut = "%d %d %d" % (angp, area, aspectRatio) cv2.putText(frameOut, stringOut, (int(center[0]), int(center[1])), cv2.FONT_HERSHEY_SIMPLEX, 1, 255) if len(possiblePoles) > 1: prevPole = possiblePoles[0] poles = [prevPole] for pole in possiblePoles: cv2.drawContours(frame, [pole[0]], -1, (0, 0, 255), 3) diff = abs( pole[1][0] - prevPole[1][0]) if (diff > 20): poles.append(pole) prevPole = pole if (len(poles) == 2): left = poles[0] right = poles[1] out = obj([True, int(right[1][0]), int(left[1][0])]) frameOut = out.draw(frameOut) cv2.drawContours(frameOut, [left[0], right[0]], -1, (0,0, 0), 3) debugFrame("out", frameOut) return out
def ProcessFrame(frame): import time #time.sleep(.1) out = obj([False, 0, 0, 0, 0, 0, 0]) frameOut = np.copy(frame) frame = norm(frame) m = cv2.mean(frame) red = dist(frame, [m[0], m[1], 255]) 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, np.mean(red) - max(np.std(red), 10) * 2.65, 255, cv2.THRESH_BINARY_INV) 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) mean, std = cv2.meanStdDev(frame) r = dist(frame, (mean[0], mean[1], mean[2])) mean, std = cv2.meanStdDev(r) r = cv2.GaussianBlur(r, (9, 9), 0) for i in range(len(contours)): epsilon = 0.045 * cv2.arcLength(contours[i], True) approx = cv2.approxPolyDP(contours[i], epsilon, True) #check if shape triangle cv2.fillConvexPoly(frameOut, approx, (255, 0, 0)) foundThreeOrFour = False """"if the approximated contour is a triangle""" if len(approx) == 3: #foundThreeOrFour = True """Finding the point opposite of the hypotenuse""" pts = [] for ptWrapper in approx: pts.append(ptWrapper[0]) #find hypotenuse maxLen = 0 maxIdx = 0 for j in range(3): #print j p1 = pts[j] #print (j+1) %3 p2 = pts[(j + 1) % 3] sideLen = math.sqrt((p1[0] - p2[0])**2 + (p1[1] - p2[1])**2) if sideLen > maxLen: maxLen = sideLen maxIdx = j p1 = pts[maxIdx] p2 = pts[(maxIdx + 1) % 3] center = pts[(maxIdx + 2) % 3] #cv2.circle(frameOut,(center[0], center[1]) , 5, color = (0,0,0), thickness = -1) elif len(approx) == 4: foundThreeOrFour = True """Figure out closest and furthest points""" pts = [] for ptWrapper in approx: pts.append(ptWrapper[0]) maxDist = 0 end1 = 0 end2 = 0 for i in range(0, len(pts)): for j in range(i, len(pts)): ptdist = math.sqrt((pts[i][0] - pts[j][0])**2 + (pts[i][1] - pts[j][1])**2) if (ptdist >= maxDist): maxDist = ptdist end1 = i end2 = j p1, p2 = pts[end1], pts[end2] centerPts = [] for i in range(len(pts)): if i != end1 and i != end2: centerPts.append(pts[i]) center = ((centerPts[0][0] + centerPts[1][0]) / 2, (centerPts[0][1] + centerPts[1][1]) / 2) #out = obj([True, int(center[0]), int(center[1]), int(endPts[0][0]), int(endPts[0][1]), int(endPts[1][0]), int(endPts[1][1])]) #frameOut = out.draw(frameOut) if foundThreeOrFour: v1 = [p1[0] - center[0], p1[1] - center[1]] v2 = [p2[0] - center[0], p2[1] - center[1]] dot = v1[0] * v2[0] + v1[1] * v2[1] """Finding magnitude of 2 shorter sides and the angle opposite of the hypotenuse""" mag1 = math.sqrt((v1[0])**2 + (v1[1])**2) mag2 = math.sqrt((v2[0])**2 + (v2[1])**2) #may increment mags and arg inside acos to be not 0 or in acos domain if mag1 == 0: mag1 += .001 if mag2 == 0: mag2 += .001 angle = math.acos(.999 * dot / (mag1 * mag2)) * 180.0 / math.pi """ checks that the biggest angle of the triangle is roughly 130 degrees and that the sides are similar sizes 130 degrees corresponds to the 45 degree bend """ MAX_ANG_DIF = 12 MAX_LEN_DIF = 60 MIN_LEN = 60 TARGET_ANGLE = 130 if mag1 > 100 or mag2 > 100: print "Angle, Mag1, Mag2: ", int(angle), int(mag1), int(mag2) #print angle if (abs(TARGET_ANGLE - abs(angle)) < MAX_ANG_DIF ) and abs(mag1 - mag2) < MAX_LEN_DIF and mag1 > MIN_LEN: out = obj([ True, int(center[0]), int(center[1]), int(p1[0]), int(p1[1]), int(p2[0]), int(p2[1]) ]) frameOut = out.draw(frameOut) debugFrame("out", frameOut) return out
def ProcessFrame(frame): out = obj() frameOut = frame.copy() frame = norm(frame) mean, std = cv2.meanStdDev(frame) r = dist(frame, (mean[0], mean[1], mean[2])) mean, std = cv2.meanStdDev(r) print "m: %d, std %d" % (mean, std) #r = frame[:, :, 2] r = cv2.GaussianBlur(r, (9, 9), 0) debugFrame("ChannelOfInterest", r) edges = cv2.Canny(r, std * 2.5, 1.2* std) debugFrame("edges", edges) height, width = frame.shape[:2] outImg = np.zeros((height,width,3), np.uint8) #frameOut = outImg """ Below is the param info for HoughCircles image is the imaged being looked at by the function method cv2.CV_HOUGH_GRADIENT is the only method available dp the size of accumulator inverse relative to input image, dp = 2 means accumulator is half dim of input image minDist minimum distance between detected circles, too small and mult neighbor circ founds, big and neighbor circ counted as same param1 bigger value input into canny, unsure why it is useful therefore not using param2 vote threshold minRadius min Radius of circle to look for maxRadius max Radius of circle to look for """ """ Find and make list of circles in the image """ drawAvg = False circleList = [] minDeg = 80.0 s = .8 d = 3.7 maxrad = 150 minrad = 30 step = 50 for radius in range(minrad + step, maxrad + 1, step): circles = cv2.HoughCircles(image = r, method = cv2.cv.CV_HOUGH_GRADIENT, dp = 4.2, minDist = 2 * radius, param2 = int((2 * radius * math.pi)/8.94), minRadius = radius - step, maxRadius = radius) msg = "minRadius: %d, maxRadius %d" % (radius - step, radius) if type(circles) != type(None): print msg + " found: %d" % (len(circles)) for circ in circles[0,:]: circleList.append(circ) if seeCircles: cv2.circle(frameOut, (circ[0], circ[1]), circ[2], (0,0,0), 2, 8, 0 ) else: print msg + " no circ found" if len(circleList) > 2: pts = [] for circle in circleList: #out.append(circle) if seeCircles: cv2.circle(frameOut, (int(circle[0]), int(circle[1])), int(circle[2]), (255,0,0), 2, 8, 0 ) cv2.circle(frameOut, (int(circle[0]), int(circle[1])), 7, (0,0,0), 2, 8, 0 ) pts.append([circle[0], circle[1]]) contour = np.array(pts, dtype=np.int32) (x,y), r = cv2.minEnclosingCircle(contour) out.append([int(x), int(y), int(r)]) #cv2.circle(frameOut, (int(x), int(y)), int(r), (0,0,0), 2, 8, 0 ) frameOut = out.draw(frameOut) out.draw(frameOut) debugFrame("houghProb", frameOut) print "-------------------------------" return out
def ProcessFrame(frame): out = obj([False, 0, 0]) frameOut = np.copy(frame) frame = norm(frame) m = cv2.mean(frame) red = dist(frame, [m[0], m[1], max(m[2] + 50, 255)]) debugFrame("red", red) (row, col, pages) = frame.shape maxArea = 30000 minArea = 1000 ret, thresh = cv2.threshold(red, np.mean(red) - np.std(red) * 1.5, 255, cv2.THRESH_BINARY_INV) kernel = np.ones((5, 5), np.uint8) kernel[:, 0:1] = 0 kernel[:, 3:5] = 0 debugFrame("threshOg", thresh) thresh = cv2.erode(thresh, kernel, iterations=1) thresh = cv2.dilate(thresh, kernel, iterations=2) debugFrame("thresh", thresh) contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) possiblePoles = [] for cont in contours: #cv2.drawContours(frame, [cont], -1, (0, 0, 255), 3) (center, (w, h), ang) = cv2.minAreaRect(cont) area = w * h if w > 0: aspectRatio = h / w if aspectRatio < 1 and aspectRatio != 0: aspectRatio = 1 / aspectRatio ang += 90 else: aspectRation = 20 angp = abs(ang) angp = abs(angp - round((angp / 180.0)) * 180) stringOut = "%d %d %d" % (angp, area, aspectRatio) cv2.putText(frameOut, stringOut, (int(center[0]), int(center[1])), cv2.FONT_HERSHEY_SIMPLEX, .5, 255) if ( angp < 10 or angp > 170 ) and area > minArea and area < maxArea and abs(aspectRatio - 9) <= 4: possiblePoles.append((cont, center)) possiblePoles = sorted(possiblePoles, key=sortPoles) for pole in possiblePoles: cv2.drawContours(frameOut, [pole[0]], -1, (0, 0, 255), 3) (center, (w, h), ang) = cv2.minAreaRect(pole[0]) aspectRatio = h / w if aspectRatio < 1: ang += 90 angp = abs(ang) angp = abs(angp - round((angp / 180)) * 180) area = h * w stringOut = "%d %d %d" % (angp, area, aspectRatio) cv2.putText(frameOut, stringOut, (int(center[0]), int(center[1])), cv2.FONT_HERSHEY_SIMPLEX, 1, 255) if len(possiblePoles) > 1: prevPole = possiblePoles[0] poles = [prevPole] for pole in possiblePoles: cv2.drawContours(frame, [pole[0]], -1, (0, 0, 255), 3) diff = abs(pole[1][0] - prevPole[1][0]) if (diff > 20): poles.append(pole) prevPole = pole if (len(poles) == 2): left = poles[0] right = poles[1] out = obj([True, int(right[1][0]), int(left[1][0])]) frameOut = out.draw(frameOut) cv2.drawContours(frameOut, [left[0], right[0]], -1, (0, 0, 0), 3) debugFrame("out", frameOut) return out
def ProcessFrame(frame): out = obj([False, 0, 0]) frameOut = np.copy(frame) frame = norm(frame) m = cv2.mean(frame) red = dist(frame, [m[0], m[1], max(m[2] + 50, 255)]) debugFrame("red", red) (row, col, pages) = frame.shape maxArea = 30000 minArea = 1000 ret, thresh = cv2.threshold(red, np.mean(red) - np.std(red) * 1.5, 255, cv2.THRESH_BINARY_INV) kernel = np.ones((5,5),np.uint8) kernel[:, 0:1] = 0 kernel[:, 3:5] = 0 debugFrame("threshOg", thresh) thresh = cv2.erode(thresh,kernel, iterations = 1) thresh = cv2.dilate(thresh, kernel, iterations = 2) debugFrame("thresh", thresh) contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) possiblePoles = [] for cont in contours: #cv2.drawContours(frame, [cont], -1, (0, 0, 255), 3) (center, (w, h), ang) = cv2.minAreaRect(cont) area = w * h if w > 0: aspectRatio = h / w if aspectRatio < 1 and aspectRatio != 0: aspectRatio = 1/aspectRatio ang+=90 else: aspectRation = 20 angp = abs(ang) angp = abs(angp - round((angp/180.0)) * 180) stringOut = "%d %d %d" % (angp, area, aspectRatio) cv2.putText(frameOut, stringOut, (int(center[0]), int(center[1])), cv2.FONT_HERSHEY_SIMPLEX, .5, 255) if (angp < 10 or angp > 170) and area > minArea and area < maxArea and abs(aspectRatio - 9) <= 4: possiblePoles.append((cont, center)) possiblePoles = sorted(possiblePoles, key = sortPoles) for pole in possiblePoles: cv2.drawContours(frameOut, [pole[0]], -1, (0, 0, 255), 3) (center, (w, h), ang) = cv2.minAreaRect(pole[0]) aspectRatio = h / w if aspectRatio < 1: ang+=90 angp = abs(ang) angp = abs(angp - round((angp/180)) * 180) area = h * w stringOut = "%d %d %d" % (angp, area, aspectRatio) cv2.putText(frameOut, stringOut, (int(center[0]), int(center[1])), cv2.FONT_HERSHEY_SIMPLEX, 1, 255) if len(possiblePoles) > 1: prevPole = possiblePoles[0] poles = [prevPole] for pole in possiblePoles: cv2.drawContours(frame, [pole[0]], -1, (0, 0, 255), 3) diff = abs( pole[1][0] - prevPole[1][0]) if (diff > 20): poles.append(pole) prevPole = pole if (len(poles) == 2): left = poles[0] right = poles[1] out = obj([True, int(right[1][0]), int(left[1][0])]) frameOut = out.draw(frameOut) cv2.drawContours(frameOut, [left[0], right[0]], -1, (0,0, 0), 3) debugFrame("out", frameOut) return out
def ProcessFrame(frame): import time #time.sleep(.1) out = obj([False, 0, 0, 0, 0, 0, 0]) frameOut = np.copy(frame) frame = norm(frame) m = cv2.mean(frame) red = dist(frame, [m[0], m[1], 255]) 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, np.mean(red) - max(np.std(red), 10) * 2.65, 255, cv2.THRESH_BINARY_INV) 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) mean, std = cv2.meanStdDev(frame) r = dist(frame, (mean[0], mean[1], mean[2])) mean, std = cv2.meanStdDev(r) r = cv2.GaussianBlur(r, (9, 9), 0) for i in range(len(contours)): epsilon = 0.045*cv2.arcLength(contours[i],True) approx = cv2.approxPolyDP(contours[i],epsilon,True) #check if shape triangle cv2.fillConvexPoly(frameOut, approx, (255,0,0)) foundThreeOrFour = False """"if the approximated contour is a triangle""" if len(approx) == 3: #foundThreeOrFour = True """Finding the point opposite of the hypotenuse""" pts = [] for ptWrapper in approx: pts.append(ptWrapper[0]) #find hypotenuse maxLen = 0 maxIdx = 0 for j in range(3): #print j p1 = pts[j] #print (j+1) %3 p2 = pts[(j + 1)%3] sideLen = math.sqrt( (p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2 ) if sideLen > maxLen: maxLen = sideLen maxIdx = j p1 = pts[maxIdx] p2 = pts[(maxIdx + 1) % 3] center = pts[(maxIdx + 2) % 3] #cv2.circle(frameOut,(center[0], center[1]) , 5, color = (0,0,0), thickness = -1) elif len(approx) == 4: foundThreeOrFour = True """Figure out closest and furthest points""" pts = [] for ptWrapper in approx: pts.append(ptWrapper[0]) maxDist = 0 end1 = 0 end2 = 0 for i in range(0,len(pts)): for j in range(i,len(pts)): ptdist = math.sqrt( (pts[i][0] - pts[j][0]) ** 2 + (pts[i][1] - pts[j][1]) ** 2 ) if(ptdist >= maxDist): maxDist = ptdist end1 = i end2 = j p1, p2 = pts[end1], pts[end2] centerPts = [] for i in range(len(pts)): if i != end1 and i != end2: centerPts.append(pts[i]) center = ( (centerPts[0][0] + centerPts[1][0]) / 2, (centerPts[0][1] + centerPts[1][1]) / 2 ) #out = obj([True, int(center[0]), int(center[1]), int(endPts[0][0]), int(endPts[0][1]), int(endPts[1][0]), int(endPts[1][1])]) #frameOut = out.draw(frameOut) if foundThreeOrFour: v1 = [p1[0] - center[0], p1[1] - center[1]] v2 = [p2[0] - center[0], p2[1] - center[1]] dot = v1[0] * v2[0] + v1[1] * v2[1] """Finding magnitude of 2 shorter sides and the angle opposite of the hypotenuse""" mag1 = math.sqrt( (v1[0]) ** 2 + (v1[1]) ** 2 ) mag2 = math.sqrt( (v2[0]) ** 2 + (v2[1]) ** 2 ) #may increment mags and arg inside acos to be not 0 or in acos domain if mag1 == 0: mag1 += .001 if mag2 == 0: mag2 += .001 angle = math.acos(.999 * dot/(mag1 * mag2)) * 180.0 / math.pi """ checks that the biggest angle of the triangle is roughly 130 degrees and that the sides are similar sizes 130 degrees corresponds to the 45 degree bend """ MAX_ANG_DIF = 12 MAX_LEN_DIF = 60 MIN_LEN = 60 TARGET_ANGLE = 130 if mag1 > 100 or mag2 > 100: print "Angle, Mag1, Mag2: ", int(angle), int(mag1), int(mag2) #print angle if( abs(TARGET_ANGLE - abs(angle)) < MAX_ANG_DIF ) and abs(mag1 - mag2) < MAX_LEN_DIF and mag1 > MIN_LEN: out = obj([True, int(center[0]), int(center[1]), int(p1[0]), int(p1[1]), int(p2[0]), int(p2[1])]) frameOut = out.draw(frameOut) debugFrame("out", frameOut) return out