def __bound_contours(roi):
"""
returns modified roi(non-destructive) and rectangles that founded by the algorithm.
@roi region of interest to find contours
@return (roi, rects)
"""
roi_copy = roi.copy()
roi_hsv = cv2.cvtColor(roi, cv2.COLOR_RGB2HSV)
# filter black color
mask1 = cv2.inRange(roi_hsv, np.array([0, 0, 0]), np.array([180, 255, 125]))
mask1 = cv2.morphologyEx(mask1, cv2.MORPH_CLOSE, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3)))
mask1 = cv2.Canny(mask1, 100, 300)
mask1 = cv2.GaussianBlur(mask1, (1, 1), 0)
mask1 = cv2.Canny(mask1, 100, 300)
# mask1 = cv2.morphologyEx(mask1, cv2.MORPH_CLOSE, cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)))
# Find contours for detected portion of the image
im2, cnts, hierarchy = cv2.findContours(mask1.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnts = sorted(cnts, key = cv2.contourArea, reverse = True)[:5] # get largest five contour area
rects = []
for c in cnts:
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.02 * peri, True)
x, y, w, h = cv2.boundingRect(approx)
if h >= 15:
# if height is enough
# create rectangle for bounding
rect = (x, y, w, h)
rects.append(rect)
cv2.rectangle(roi_copy, (x, y), (x+w, y+h), (0, 255, 0), 1);
return (roi_copy, rects)
python类contourArea()的实例源码
def find_squares(img):
img = cv2.GaussianBlur(img, (5, 5), 0)
squares = []
for gray in cv2.split(img):
for thrs in xrange(0, 255, 26):
if thrs == 0:
bin = cv2.Canny(gray, 0, 50, apertureSize=5)
bin = cv2.dilate(bin, None)
else:
retval, bin = cv2.threshold(gray, thrs, 255, cv2.THRESH_BINARY)
bin, contours, hierarchy = cv2.findContours(bin, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
cnt_len = cv2.arcLength(cnt, True)
cnt = cv2.approxPolyDP(cnt, 0.02 * cnt_len, True)
if len(cnt) == 4 and cv2.contourArea(cnt) > 1000 and cv2.isContourConvex(cnt):
cnt = cnt.reshape(-1, 2)
max_cos = np.max([angle_cos(cnt[i], cnt[(i + 1) % 4], cnt[(i + 2) % 4]) for i in xrange(4)])
if max_cos < 0.1:
squares.append(cnt)
return squares
def find_biggest_contour(image):
# Copy
image = image.copy()
#input, gives all the contours, contour approximation compresses horizontal,
#vertical, and diagonal segments and leaves only their end points. For example,
#an up-right rectangular contour is encoded with 4 points.
#Optional output vector, containing information about the image topology.
#It has as many elements as the number of contours.
#we dont need it
_, contours, hierarchy = cv2.findContours(image, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
# Isolate largest contour
contour_sizes = [(cv2.contourArea(contour), contour) for contour in contours]
biggest_contour = max(contour_sizes, key=lambda x: x[0])[1]
mask = np.zeros(image.shape, np.uint8)
cv2.drawContours(mask, [biggest_contour], -1, 255, -1)
return biggest_contour, mask
def find_triangles(filename):
FIRST = 0
RED = (0, 0, 255)
THICKNESS = 3
copy = img = cv2.imread(filename)
grey_img = cv2.imread(file_name, cv2.IMREAD_GRAYSCALE)
ret, thresh = cv2.threshold(grey_img, 127, 255, 1)
contours, h = cv2.findContours(thresh, 1, 2)
largest = None
for contour in countours:
approx = cv2.approxPolyDP(contour,0.01*cv2.arcLength(contour,True),True)
if len(approx) == 3:
#triangle found
if largest is None or cv2.contourArea(contour) > cv2.contourArea(largest):
largest = contour
#write file
cv2.drawContours(copy, [largest], FIRST, RED, THICKNESS)
cv2.imwrite(filename +"_result", copy)
def remove_borders(image):
ratio = image.shape[0] / 500.0
orig = image.copy()
image = resize(image, height=500)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (5, 5), 0)
edged = cv2.Canny(gray, 75, 200)
_, cnts, _ = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cv2.imshow('edged', edged)
cnts = sorted(cnts, key=cv2.contourArea, reverse=True)
screenCnt = None
for c in cnts:
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.02 * peri, True)
print(len(approx) == 4)
if len(approx) == 4:
screenCnt = approx
break
cv2.drawContours(image, [screenCnt], -1, (0, 255, 0), 2)
if screenCnt is not None and len(screenCnt) > 0:
return four_point_transform(orig, screenCnt.reshape(4, 2) * ratio)
return orig
def find_squares(img):
img = cv2.GaussianBlur(img, (5, 5), 0)
squares = []
for gray in cv2.split(img):
for thrs in xrange(0, 255, 26):
if thrs == 0:
bin = cv2.Canny(gray, 0, 50, apertureSize=5)
bin = cv2.dilate(bin, None)
else:
_retval, bin = cv2.threshold(gray, thrs, 255, cv2.THRESH_BINARY)
contours, _hierarchy = find_contours(bin, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
x, y, w, h = cv2.boundingRect(cnt)
cnt_len = cv2.arcLength(cnt, True)
cnt = cv2.approxPolyDP(cnt, 0.02*cnt_len, True)
area = cv2.contourArea(cnt)
if len(cnt) == 4 and 20 < area < 1000 and cv2.isContourConvex(cnt):
cnt = cnt.reshape(-1, 2)
max_cos = np.max([angle_cos( cnt[i], cnt[(i+1) % 4], cnt[(i+2) % 4] ) for i in xrange(4)])
if max_cos < 0.1:
if (1 - (float(w) / float(h)) <= 0.07 and 1 - (float(h) / float(w)) <= 0.07):
squares.append(cnt)
return squares
def sizeFiltering(contours):
"""
this function filters out the smaller retroreflector (as well as any noise) by size
"""
if len(contours) == 0:
print "sizeFiltering: Error, no contours found"
return 0
big = contours[0]
for c in contours:
if type(c) and type(big) == numpy.ndarray:
if cv2.contourArea(c) > cv2.contourArea(big):
big = c
else:
print type(c) and type(big)
return 0
x,y,w,h = cv2.boundingRect(big)
return big
def homography(self, img, outdir_name=''):
orig = img
# 2??????
gray = cv2.cvtColor(orig, cv2.COLOR_BGR2GRAY)
gauss = cv2.GaussianBlur(gray, (5, 5), 0)
canny = cv2.Canny(gauss, 50, 150)
# 2??????????
contours = cv2.findContours(canny, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)[1]
# ???????????
contours.sort(key=cv2.contourArea, reverse=True)
if len(contours) > 0:
arclen = cv2.arcLength(contours[0], True)
# ???????????
approx = cv2.approxPolyDP(contours[0], 0.01 * arclen, True)
# warp = approx.copy()
if len(approx) >= 4:
self.last_approx = approx.copy()
elif self.last_approx is not None:
approx = self.last_approx
else:
approx = self.last_approx
rect = self.get_rect_by_points(approx)
# warped = self.transform_by4(orig, warp[:, 0, :])
return orig[rect[0]:rect[1], rect[2]:rect[3]]
def find_squares(img, cos_limit = 0.1):
print('search for squares with threshold %f' % cos_limit)
img = cv2.GaussianBlur(img, (5, 5), 0)
squares = []
for gray in cv2.split(img):
for thrs in xrange(0, 255, 26):
if thrs == 0:
bin = cv2.Canny(gray, 0, 50, apertureSize=5)
bin = cv2.dilate(bin, None)
else:
retval, bin = cv2.threshold(gray, thrs, 255, cv2.THRESH_BINARY)
bin, contours, hierarchy = cv2.findContours(bin, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
cnt_len = cv2.arcLength(cnt, True)
cnt = cv2.approxPolyDP(cnt, 0.02*cnt_len, True)
if len(cnt) == 4 and cv2.contourArea(cnt) > 1000 and cv2.isContourConvex(cnt):
cnt = cnt.reshape(-1, 2)
max_cos = np.max([angle_cos( cnt[i], cnt[(i+1) % 4], cnt[(i+2) % 4] ) for i in xrange(4)])
if max_cos < cos_limit :
squares.append(cnt)
else:
#print('dropped a square with max_cos %f' % max_cos)
pass
return squares
###
### Version V2. Collect meta-data along the way, with commentary added.
###
def find_center(self, name, frame, mask, min_radius):
if name not in self.pts:
self.pts[name] = deque(maxlen=self.params['tracking']['buffer_size'])
# find contours in the mask and initialize the current (x, y) center of the ball
cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]
# only proceed if at least one contour was found
if len(cnts) > 0:
# find the largest contour in the mask, then use it to compute the minimum enclosing circle and centroid
c = max(cnts, key=cv2.contourArea)
((x, y), radius) = cv2.minEnclosingCircle(c)
center = (int(x), int(y))
# only proceed if the radius meets a minimum size
if radius > min_radius:
# draw the circle and centroid on the frame, then update the list of tracked points
cv2.circle(frame, center, int(radius), (0, 255, 255), 2)
cv2.circle(frame, center, 5, (0, 0, 255), -1)
self.pts[name].appendleft(center)
smooth_points = 8
return (int(np.mean([self.pts[name][i][0] for i in range(min(smooth_points, len(self.pts[name])))])),
int(np.mean([self.pts[name][i][1] for i in range(min(smooth_points, len(self.pts[name])))]))), radius
return None, None
Artificial-potential-controller-2.py 文件源码
项目:Artificial-Potential-Field
作者: vampcoder
项目源码
文件源码
阅读 23
收藏 0
点赞 0
评论 0
def classify(img):
cimg = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img2 = cv2.medianBlur(cimg, 13)
ret, thresh1 = cv2.threshold(cimg, 100, 120, cv2.THRESH_BINARY)
t2 = copy.copy(thresh1)
x, y = thresh1.shape
arr = np.zeros((x, y, 3), np.uint8)
final_contours = []
image, contours, hierarchy = cv2.findContours(t2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
#cv2.imshow('image', image)
#k = cv2.waitKey(0)
for i in range(len(contours)):
cnt = contours[i]
if cv2.contourArea(cnt) > 3000 and cv2.contourArea(cnt) < 25000:
cv2.drawContours(img, [cnt], -1, [0, 255, 255])
cv2.fillConvexPoly(arr, cnt, [255, 255, 255])
final_contours.append(cnt)
#cv2.imshow('arr', arr)
#k = cv2.waitKey(0)
return arr
def __init__(self, rubiks_parent, index, contour, heirarchy):
self.rubiks_parent = rubiks_parent
self.index = index
self.contour = contour
self.heirarchy = heirarchy
peri = cv2.arcLength(contour, True)
self.approx = cv2.approxPolyDP(contour, 0.1 * peri, True)
self.area = cv2.contourArea(contour)
self.corners = len(self.approx)
self.width = None
# compute the center of the contour
M = cv2.moments(contour)
if M["m00"]:
self.cX = int(M["m10"] / M["m00"])
self.cY = int(M["m01"] / M["m00"])
else:
self.cX = None
self.cY = None
def diagContour(image):
#Find contours in the image the first and last returns dont matter so the _ is just a placeholder to ignore them
_, contours, _ = cv2.findContours(image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
#The contouring operation does some weird stuff to the image so this line just fills the whole thing with black
image.fill(0)
boundingRect = []
firstFail = []
#Loops through all contours bigger than minArea pixels. That number is tweakable and determined by testing
for j in [i for i in contours if cv2.contourArea(i) > minArea]:
#br is a (list/tuple)? of the form x, y, width, height where (x,y) is the (top/bottom)? (left/right)? corner
br = cv2.boundingRect(j)
if(abs(br[2]/br[3] - INDASPECT) < indAspectTol and cv2.contourArea(j)/(br[2]*br[3]) > covTol):
boundingRect.append(br)
else:
firstFail.append([br, br[2]/br[3], cv2.contourArea(j)/(br[2]*br[3])])
secondRound = []
for x in range(0, len(boundingRect)):
for y in range(x+1, len(boundingRect)):
i = boundingRect[x]
j = boundingRect[y]
secondRound.append([(x,y,i,j), (abs(i[1]-j[1]), i[3]/2), abs(i[0]-j[0])/i[1]])
for x in secondRound:
if(x[1][0] < x[1][1] and x[2] - GRPASPECT < grpAspectTol):
return [x[0][2], x[0][3]]
return None;
def findEllipses(edges):
contours, _ = cv2.findContours(edges.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
ellipseMask = np.zeros(edges.shape, dtype=np.uint8)
contourMask = np.zeros(edges.shape, dtype=np.uint8)
pi_4 = np.pi * 4
for i, contour in enumerate(contours):
if len(contour) < 5:
continue
area = cv2.contourArea(contour)
if area <= 100: # skip ellipses smaller then 10x10
continue
arclen = cv2.arcLength(contour, True)
circularity = (pi_4 * area) / (arclen * arclen)
ellipse = cv2.fitEllipse(contour)
poly = cv2.ellipse2Poly((int(ellipse[0][0]), int(ellipse[0][1])), (int(ellipse[1][0] / 2), int(ellipse[1][1] / 2)), int(ellipse[2]), 0, 360, 5)
# if contour is circular enough
if circularity > 0.6:
cv2.fillPoly(ellipseMask, [poly], 255)
continue
# if contour has enough similarity to an ellipse
similarity = cv2.matchShapes(poly.reshape((poly.shape[0], 1, poly.shape[1])), contour, cv2.cv.CV_CONTOURS_MATCH_I2, 0)
if similarity <= 0.2:
cv2.fillPoly(contourMask, [poly], 255)
return ellipseMask, contourMask
def get_contours(image, polydb=0.1, contour_range=7):
# find the contours in the edged image, keeping only the largest ones, and initialize the screen contour
contours = _findContours(image, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnts = sorted(contours, key = cv2.contourArea, reverse = True)[:contour_range]
# loop over the contours
screenCnt = None
for c in cnts:
# approximate the contour
peri = cv2.arcLength(c, True) #finds the Contour Perimeter
approx = cv2.approxPolyDP(c, polydb * peri, True)
# if our approximated contour has four points, then we can assume that we have found our screen
if len(approx) == 4:
screenCnt = approx
break
if screenCnt is None:
raise EdgeNotFound()
# sometimes the algorythm finds a strange non-convex shape. The shape conforms to the card but its not complete, so then just complete the shape into a convex form
if not cv2.isContourConvex(screenCnt):
screenCnt = cv2.convexHull(screenCnt)
x,y,w,h = cv2.boundingRect(screenCnt)
screenCnt = numpy.array([[[x, y]], [[x+w, y]], [[x+w, y+h]], [[x, y+h]]])
return screenCnt
def GetImageContour(self):
thresholdImage = self.__convertImagetoBlackWhite() #B & W with adaptive threshold
thresholdImage = cv.Canny(thresholdImage, 100, 200) #Edges by canny edge detection
thresholdImage, contours, hierarchy = cv.findContours(
thresholdImage, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
self.Contours = contours
# uncomment this to see the contours on the image
# cv2.drawContours(thresholdImage, contours, -1, (0,255,0), 3)
# patternFindingObj=PatternFinding()
# areas= [cv.contourArea(contour) for contour in contours]
# for index in xrange(len(contours)):
# IsPattern=self.IsPossibleQRContour(index)
# if IsPattern is True:
# x,y,w,h=cv.boundingRect(contours[index])
# cv.rectangle(self.imageOriginal,(x,y),(x+w,y+h),(0,0,255),2)
# cv.imshow("hello",self.imageOriginal)
# maxAreaIndex=np.argmax(areas)
# x,y,w,h=cv.boundingRect(contours[maxAreaIndex])
# cv.rectangle(self.image2,(x,y),(x+w,y+h),(0,255,0),2)
# cv.imshow("hello",self.imageOriginal)
# cv.waitKey(0)
#cv.destroyAllWindows()
contour_group = (thresholdImage, contours, hierarchy)
return contour_group
def findSquare( self,frame ):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (7, 7), 0)
edged = cv2.Canny(blurred, 60, 60)
# find contours in the edge map
(cnts, _) = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# loop over our contours to find hexagon
cnts = sorted(cnts, key = cv2.contourArea, reverse = True)[:50]
screenCnt = None
for c in cnts:
# approximate the contour
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.004 * peri, True)
# if our approximated contour has four points, then
# we can assume that we have found our squeare
if len(approx) >= 4:
screenCnt = approx
x,y,w,h = cv2.boundingRect(c)
cv2.drawContours(image, [approx], -1, (0, 0, 255), 1)
#cv2.imshow("Screen", image)
#create the mask and remove rest of the background
mask = np.zeros(image.shape[:2], dtype = "uint8")
cv2.drawContours(mask, [screenCnt], -1, 255, -1)
masked = cv2.bitwise_and(image, image, mask = mask)
#cv2.imshow("Masked",masked )
#crop the masked image to to be compared to referance image
cropped = masked[y:y+h,x:x+w]
#scale the image so it is fixed size as referance image
cropped = cv2.resize(cropped, (200,200), interpolation =cv2.INTER_AREA)
return cropped
def imgSeg_contour(img, b,g,r, per):
lower = np.array([0, 0, 0])
upper = np.array([b,g,r])
shapeMask = cv2.inRange(img, lower, upper)
#http://stackoverflow.com/questions/27746089/python-computer-vision-contours-too-many-values-to-unpack
_, cnts, hierarchy = cv2.findContours(shapeMask.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = sorted(cnts, key = cv2.contourArea, reverse = True)[:4]
for c in cnts:
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, per * peri, True) ### 0.04 ###
if (len(approx) >= 4) and (len(approx) < 6):
break
return approx
utils.py 文件源码
项目:kaggle-dstl-satellite-imagery-feature-detection
作者: u1234x1234
项目源码
文件源码
阅读 19
收藏 0
点赞 0
评论 0
def polygonize_cv(mask, epsilon=1., min_area=10.):
contours, hierarchy = cv2.findContours(mask, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_TC89_KCOS)
# create approximate contours to have reasonable submission size
approx_contours = [cv2.approxPolyDP(cnt, epsilon, True)
for cnt in contours]
approx_contours = contours
if not contours:
return MultiPolygon()
# now messy stuff to associate parent and child contours
cnt_children = defaultdict(list)
child_contours = set()
assert hierarchy.shape[0] == 1
# http://docs.opencv.org/3.1.0/d9/d8b/tutorial_py_contours_hierarchy.html
for idx, (_, _, _, parent_idx) in enumerate(hierarchy[0]):
if parent_idx != -1:
child_contours.add(idx)
cnt_children[parent_idx].append(approx_contours[idx])
# create actual polygons filtering by area (removes artifacts)
all_polygons = []
for idx, cnt in enumerate(approx_contours):
if idx not in child_contours and cv2.contourArea(cnt) >= min_area:
assert cnt.shape[1] == 1
poly = Polygon(
shell=cnt[:, 0, :],
holes=[c[:, 0, :] for c in cnt_children.get(idx, [])
if cv2.contourArea(c) >= min_area])
all_polygons.append(poly)
# approximating polygons might have created invalid ones, fix them
all_polygons = MultiPolygon(all_polygons)
if not all_polygons.is_valid:
all_polygons = all_polygons.buffer(0)
# Sometimes buffer() converts a simple Multipolygon to just a Polygon,
# need to keep it a Multi throughout
if all_polygons.type == 'Polygon':
all_polygons = MultiPolygon([all_polygons])
return all_polygons
def cannyThresholding(self, contour_retrieval_mode = cv2.RETR_LIST):
'''
contour_retrieval_mode is passed through as second argument to cv2.findContours
'''
# Attempt to match edges found in blue, green or red channels : collect all
channel = 0
for gray in cv2.split(self.img):
channel += 1
print('channel %d ' % channel)
title = self.tgen.next('channel-%d' % channel)
if self.show: ImageViewer(gray).show(window = title, destroy = self.destroy, info = self.info, thumbnailfn = title)
found = {}
for thrs in xrange(0, 255, 26):
print('Using threshold %d' % thrs)
if thrs == 0:
print('First step')
bin = cv2.Canny(gray, 0, 50, apertureSize=5)
title = self.tgen.next('canny-%d' % channel)
if self.show: ImageViewer(bin).show(window = title, destroy = self.destroy, info = self.info, thumbnailfn = title)
bin = cv2.dilate(bin, None)
title = self.tgen.next('canny-dilate-%d' % channel)
if self.show: ImageViewer(bin).show(window = title, destroy = self.destroy, info = self.info, thumbnailfn = title)
else:
retval, bin = cv2.threshold(gray, thrs, 255, cv2.THRESH_BINARY)
title = self.tgen.next('channel-%d-threshold-%d' % (channel, thrs))
if self.show: ImageViewer(bin).show(window='Next threshold (n to continue)', destroy = self.destroy, info = self.info, thumbnailfn = title)
bin, contours, hierarchy = cv2.findContours(bin, contour_retrieval_mode, cv2.CHAIN_APPROX_SIMPLE)
title = self.tgen.next('channel-%d-threshold-%d-contours' % (channel, thrs))
if self.show: ImageViewer(bin).show(window = title, destroy = self.destroy, info = self.info, thumbnailfn = title)
if contour_retrieval_mode == cv2.RETR_LIST or contour_retrieval_mode == cv2.RETR_EXTERNAL:
filteredContours = contours
else:
filteredContours = []
h = hierarchy[0]
for component in zip(contours, h):
currentContour = component[0]
currentHierarchy = component[1]
if currentHierarchy[3] < 0:
# Found the outermost parent component
filteredContours.append(currentContour)
print('Contours filtered. Input %d Output %d' % (len(contours), len(filteredContours)))
time.sleep(5)
for cnt in filteredContours:
cnt_len = cv2.arcLength(cnt, True)
cnt = cv2.approxPolyDP(cnt, 0.02*cnt_len, True)
cnt_len = len(cnt)
cnt_area = cv2.contourArea(cnt)
cnt_isConvex = cv2.isContourConvex(cnt)
if cnt_len == 4 and (cnt_area > self.area_min and cnt_area < self.area_max) and cnt_isConvex:
cnt = cnt.reshape(-1, 2)
max_cos = np.max([angle_cos( cnt[i], cnt[(i+1) % 4], cnt[(i+2) % 4] ) for i in xrange(4)])
if max_cos < self.cos_limit :
sq = Square(cnt, cnt_area, cnt_isConvex, max_cos)
self.squares.append(sq)
else:
#print('dropped a square with max_cos %f' % max_cos)
pass
found[thrs] = len(self.squares)
print('Found %d quadrilaterals with threshold %d' % (len(self.squares), thrs))
def cropCircle(img, resize=None):
if resize:
if (img.shape[0] > img.shape[1]):
tile_size = (int(img.shape[1] * resize / img.shape[0]), resize)
else:
tile_size = (resize, int(img.shape[0] * resize / img.shape[1]))
img = cv2.resize(img, dsize=tile_size, interpolation=cv2.INTER_CUBIC)
else:
tile_size = img.shape
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY);
_, thresh = cv2.threshold(gray, 10, 255, cv2.THRESH_BINARY)
_, contours, _ = cv2.findContours(thresh.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
main_contour = sorted(contours, key=cv2.contourArea, reverse=True)[0]
ff = np.zeros((gray.shape[0], gray.shape[1]), 'uint8')
cv2.drawContours(ff, main_contour, -1, 1, 15)
ff_mask = np.zeros((gray.shape[0] + 2, gray.shape[1] + 2), 'uint8')
cv2.floodFill(ff, ff_mask, (int(gray.shape[1] / 2), int(gray.shape[0] / 2)), 1)
rect = maxRect(ff)
rectangle = [min(rect[0], rect[2]), max(rect[0], rect[2]), min(rect[1], rect[3]), max(rect[1], rect[3])]
img_crop = img[rectangle[0]:rectangle[1], rectangle[2]:rectangle[3]]
cv2.rectangle(ff, (min(rect[1], rect[3]), min(rect[0], rect[2])), (max(rect[1], rect[3]), max(rect[0], rect[2])), 3,
2)
return [img_crop, rectangle, tile_size]
def getContours(img,kernel=(10,10)):
#Define kernel
kernel = np.ones(kernel, np.uint8)
#Open to erode small patches
thresh = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
#Close little holes
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE,kernel, iterations=4)
#Find contours
#contours=skimsr.find_contours(thresh,0)
thresh=thresh.astype('uint8')
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
areas=[]
for c in contours:
areas.append(cv2.contourArea(c))
return contours,thresh,areas
def findSignificantContours(img, sobel_8u, sobel):
image, contours, heirarchy = cv2.findContours(sobel_8u, \
cv2.RETR_EXTERNAL, \
cv2.CHAIN_APPROX_SIMPLE)
mask = np.ones(image.shape[:2], dtype="uint8") * 255
level1 = []
for i, tupl in enumerate(heirarchy[0]):
if tupl[3] == -1:
tupl = np.insert(tupl, 0, [i])
level1.append(tupl)
significant = []
tooSmall = sobel_8u.size * 10 / 100
for tupl in level1:
contour = contours[tupl[0]];
area = cv2.contourArea(contour)
if area > tooSmall:
cv2.drawContours(mask, \
[contour], 0, (0, 255, 0), \
2, cv2.LINE_AA, maxLevel=1)
significant.append([contour, area])
significant.sort(key=lambda x: x[1])
significant = [x[0] for x in significant];
peri = cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, 0.02 * peri, True)
mask = sobel.copy()
mask[mask > 0] = 0
cv2.fillPoly(mask, significant, 255, 0)
mask = np.logical_not(mask)
img[mask] = 0;
return img
def categorize_contour(
contour,
perimeter_heuristic=PERIMETER_HEURISTIC,
linear_heuristic=LINEAR_HEURISTIC):
"""
Categorize a contour as a box, a line, or speck
"""
area = cv2.contourArea(contour)
perimeter = cv2.arcLength(contour, True)
if perimeter <= perimeter_heuristic:
return CONTOUR_SPECK
ratio = area / perimeter
if ratio < linear_heuristic:
return CONTOUR_LINE
else:
return CONTOUR_BOX
def draw_contours(self):
""""""
# contours all the objects found
# (findContours changes the source image,
# hence copy)
contours, _ = cv2.findContours(self.mask.copy(),
cv2.RETR_TREE,
cv2.CHAIN_APPROX_SIMPLE)
# rectangles
for contour in contours:
size = cv2.contourArea(contour)
if size > self.threshold: # only larger objects
ret_x, ret_y, ret_w, ret_h = cv2.boundingRect(contour)
cv2.rectangle(self.display, (ret_x, ret_y),
(ret_x+ret_w,
ret_y+ret_h),
(0, 255, 255), 2)
def find_contours(mask, smooth_factor=0.005):
""" Find the contours in a given mask """
border = 5
# Canny detection breaks down with the edge of the image
my_mask = cv2.copyMakeBorder(mask, border, border, border, border,
cv2.BORDER_CONSTANT, value=(0, 0, 0))
my_mask = cv2.cvtColor(my_mask, cv2.COLOR_BGR2GRAY)
if is_cv2():
contours, _ = cv2.findContours(my_mask, cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
else:
_, contours, _ = cv2.findContours(my_mask, cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
# shift the contours back down
for contour in contours:
for pnt in contour:
if pnt[0][1] > border:
pnt[0][1] = pnt[0][1] - border
else:
pnt[0][1] = 0
if pnt[0][0] > border:
pnt[0][0] = pnt[0][0] - border
else:
pnt[0][0] = 0
closed_contours = []
for contour in contours:
epsilon = smooth_factor*cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, epsilon, True)
area = cv2.contourArea(approx)
# if they are too small they are not edges
if area < 200:
continue
closed_contours.append(approx)
return closed_contours
def find_likely_rectangles(contours, sigma):
contours = sorted(contours, key=cv2.contourArea, reverse=True)[:10]
possible = []
for c in contours:
# approximate the contour
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, sigma * peri, True)
box = make_box(approx)
possible.append(box)
return possible
find_rect_and_transform.py 文件源码
项目:quadrilaterals-rectifier
作者: michal2229
项目源码
文件源码
阅读 23
收藏 0
点赞 0
评论 0
def extract_rect(im):
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imgray, 127, 255, 0)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# finding contour with max area
largest = None
for cnt in contours:
if largest == None or cv2.contourArea(cnt) > cv2.contourArea(largest):
largest = cnt
peri = cv2.arcLength(largest, True)
appr = cv2.approxPolyDP(largest, 0.02 * peri, True)
#cv2.drawContours(im, appr, -1, (0,255,0), 3)
points_list = [[i[0][0], i[0][1]] for i in appr]
left = sorted(points_list, key = lambda p: p[0])[0:2]
right = sorted(points_list, key = lambda p: p[0])[2:4]
print("l " + str(left))
print("r " + str(right))
lu = sorted(left, key = lambda p: p[1])[0]
ld = sorted(left, key = lambda p: p[1])[1]
ru = sorted(right, key = lambda p: p[1])[0]
rd = sorted(right, key = lambda p: p[1])[1]
print("lu " + str(lu))
print("ld " + str(ld))
print("ru " + str(ru))
print("rd " + str(rd))
lu_ = [ (lu[0] + ld[0])/2, (lu[1] + ru[1])/2 ]
ld_ = [ (lu[0] + ld[0])/2, (ld[1] + rd[1])/2 ]
ru_ = [ (ru[0] + rd[0])/2, (lu[1] + ru[1])/2 ]
rd_ = [ (ru[0] + rd[0])/2, (ld[1] + rd[1])/2 ]
print("lu_ " + str(lu_))
print("ld_ " + str(ld_))
print("ru_ " + str(ru_))
print("rd_ " + str(rd_))
src_pts = np.float32(np.array([lu, ru, rd, ld]))
dst_pts = np.float32(np.array([lu_, ru_, rd_, ld_]))
h,w,b = im.shape
H, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
print("H" + str(H))
imw = cv2.warpPerspective(im, H, (w, h))
return imw[lu_[1]:rd_[1], lu_[0]:rd_[0]] # cropping image
def _find_size_candidates(self, image):
binary_image = self._filter_image(image)
_, contours, _ = cv2.findContours(binary_image,
cv2.RETR_LIST,
cv2.CHAIN_APPROX_SIMPLE)
size_candidates = []
for contour in contours:
bounding_rect = cv2.boundingRect(contour)
contour_area = cv2.contourArea(contour)
if self._is_valid_contour(contour_area, bounding_rect):
candidate = (bounding_rect[2] + bounding_rect[3]) / 2
size_candidates.append(candidate)
return size_candidates
def camera_gesture_trigger():
# Capture frame-by-frame
ret, frame = cap.read()
# Our operations on the frame come here
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray,(5,5),0)
ret,thresh1 = cv2.threshold(blur,70,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
contours, hierarchy = cv2.findContours(thresh1,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
max_area=0
for i in range(len(contours)):
cnt=contours[i]
area = cv2.contourArea(cnt)
if(area>max_area):
max_area=area
ci=i
cnt=contours[ci]
hull = cv2.convexHull(cnt)
moments = cv2.moments(cnt)
cnt = cv2.approxPolyDP(cnt,0.01*cv2.arcLength(cnt,True),True)
hull = cv2.convexHull(cnt,returnPoints = False)
defects = cv2.convexityDefects(cnt,hull)
if defects is not None:
if defects.shape[0] >= 5:
return 1
return 0