def find_corner_in_full_scale(self,point): point= self.m_d.scale_up(point) scale = self.m_d.scale self.m_d.set_scale(0) gray_img = self.m_d.gray_img canny_img = self.m_d.canny_img x,y = point cr = correct_rectangle((x-5,y-5,10,10), cv.GetSize(gray_img)) for img in [gray_img,canny_img]: cv.SetImageROI(img, cr) cv.Canny(gray_img, canny_img, 300, 500) conts = cv.FindContours(canny_img, cv.CreateMemStorage(), cv.CV_RETR_LIST,(cr[0],cr[1])) db.DrawContours(self.m_d.tmp_img, conts, (255,255,255), (128,128,128), 10) min =10 min_point = None while conts: for c in conts: vec = vector(point,c) len =length(vec) if len<min: min = len min_point = c conts.h_next() self.m_d.set_scale(scale) return min_point
def get_candidates(self, m_d): ''' Get candidates for this corner from new image @param m_d: marker_detector ''' # if this corner is wider then MAX_CORNER_ANGLE, we probably won't # find it anyway. Instead lets find narrow corners and calculate its # position if self.angle > MAX_CORNER_ANGLE: return [] cr = self.get_rectangle(m_d) cr = correct_rectangle(cr, m_d.size) if cr is None: return [] m_d.set_ROI(cr) tmp_img = m_d.tmp_img gray_img = m_d.gray_img bw_img = m_d.bw_img canny = m_d.canny_img cv.Copy(gray_img, tmp_img) cv.Threshold(gray_img, bw_img, 125, 255, cv.CV_THRESH_OTSU) if self.black_inside > 0: cv.Not(bw_img, bw_img) cv.Canny(gray_img, canny, 300, 500) cv.Or(bw_img, canny, bw_img) tmpim = m_d.canny_img cv.Copy(bw_img, tmpim) cv.Set2D(tmpim, 1, 1, 255) conts = cv.FindContours(tmpim, cv.CreateMemStorage(), cv.CV_RETR_EXTERNAL) cv.Zero(tmpim) m_d.set_ROI() cv.SetImageROI(tmpim, cr) result = [] while conts: aconts = cv.ApproxPoly(conts, cv.CreateMemStorage(), cv.CV_POLY_APPROX_DP, 2) nconts = list(aconts) cv.PolyLine(tmpim, [nconts], True, (255, 255, 255)) self._append_candidates_from_conts(cr, result, nconts, m_d) conts = conts.h_next() # print result # db.show([tmpim,m_d.draw_img], 'tmpim', 0, 0, 0) return result
def find_old_markers(self): ''' Find markers using their previous position ''' #print "find old" self.borders = [] for scale in range(0, -1, -1): self.set_scale(scale) for mar in self.not_found: if mar.find_corners(): self.not_found.remove(mar) return if len(self.not_found) == 0: return # if there are some undetected markers, try to find them again. This # time bw_img has more accurate tresholding, so maybe we will find them if len(self.borders) == 0: return (x, y, wx, wy) = cv.BoundingRect(self.borders) cv.ResetImageROI(self.img) rect = correct_rectangle((x - wx / 2, y - wy / 2, wx * 1.5, wy * 1.5), self.size)
def get_candidates(self, m_d): ''' Get candidates for this corner from new image @param m_d: marker_detector ''' # if this corner is wider then MAX_CORNER_ANGLE, we probably won't # find it anyway. Instead lets find narrow corners and calculate its # position if self.angle > MAX_CORNER_ANGLE: return [] cr = self.get_rectangle(m_d) cr = correct_rectangle(cr, m_d.size) if cr is None: return [] m_d.set_ROI(cr) tmp_img = m_d.tmp_img gray_img = m_d.gray_img bw_img = m_d.bw_img canny = m_d.canny_img cv.Copy(gray_img, tmp_img) cv.Threshold(gray_img, bw_img, 125, 255, cv.CV_THRESH_OTSU) if self.black_inside>0: cv.Not(bw_img, bw_img) cv.Canny(gray_img, canny, 300, 500) cv.Or(bw_img, canny, bw_img) tmpim = m_d.canny_img cv.Copy(bw_img, tmpim) cv.Set2D(tmpim, 1, 1, 255) conts = cv.FindContours(tmpim, cv.CreateMemStorage(), cv.CV_RETR_EXTERNAL); cv.Zero(tmpim) m_d.set_ROI() cv.SetImageROI(tmpim, cr) result = [] while conts: aconts = cv.ApproxPoly(conts, cv.CreateMemStorage(), cv.CV_POLY_APPROX_DP, 2) nconts = list(aconts) cv.PolyLine(tmpim, [nconts], True, (255,255,255)) self._append_candidates_from_conts(cr, result, nconts, m_d) conts = conts.h_next() # print result # db.show([tmpim,m_d.draw_img], 'tmpim', 0, 0, 0) return result
def find_better_point(self, from_, direction, predicted_length, range=20): ''' Tries to find better corner arm - goes from from_ using vector direction on a line to find last visible point on this line @param from_: @param tpredicted_length: predicted length of this side @param direction: ''' img = self.bw_img timg = self.tmp_img L1 = predicted_length * 1.2 vec = direction L2 = length(vec) vec = add((0, 0), vec, L1 / L2) #vector towards direction of length of old side vec1 = rotateVec(vec, d2r(range)) vec2 = rotateVec(vec, d2r(-range)) x, y = from_ cv.ResetImageROI(img) size = cv.GetSize(img) border_points = [add(from_, vec1), add(from_, vec2), (x - 5, y - 5), (x + 5, y + 5)] (x, y, wx, wy) = cv.BoundingRect(border_points) crect = correct_rectangle((x - 3, y - 3, wx + 6, wy + 6), size) [cv.SetImageROI(i, crect) for i in [img, timg, self.gray_img]] self.bounds.extend(cvrect(crect)) cv.Threshold(self.gray_img, img, 125, 255, cv.CV_THRESH_OTSU) cv.Not(img, timg) cv.Canny(self.gray_img, img, 300, 500) cv.Or(img, timg,timg) rect = cvrect(crect) cv.Set2D(timg, 1, 1, (30, 30, 30)) conts = cv.FindContours(timg, cv.CreateMemStorage(), cv.CV_RETR_EXTERNAL) db.DrawContours(timg, conts, (255, 255, 255), (128, 128, 128), 10) cv.Zero(timg) fr = add(from_, rect[0], -1) ans = [] while conts: cont = cv.ApproxPoly(conts, cv.CreateMemStorage(), cv.CV_POLY_APPROX_DP, parameter=2, parameter2=0) cv.DrawContours(timg, cont, (255, 255, 255), (128, 128, 128), 10) cont = list(cont) L = len(cont) for i, p in enumerate(cont): if length(vector(fr, p)) < 5: prev = cont[(i - 1 + L) % L] next = cont[(i + 1) % L] ans.append(vector(fr, prev)) ans.append(vector(fr, next)) conts = conts.h_next() [cv.ResetImageROI(i) for i in [self.gray_img, timg, img]] if len(ans) == 0: # we didn't find corresponding corner, # that means it wasn't really a corner return None if len(ans) == 2 and ans[0] == ans[1]: return add(from_, direction) min = math.pi min_index = 0 for i, v in enumerate(ans): tmp = vectorAngle(vec, v) if tmp < min: min = tmp min_index = i ans = ans[min_index] if length(ans)+1< L2: # the point we just found is closer then the previous one return add(from_,direction) abs_point = add(from_, ans) if point_on_edge(abs_point, crect): if not point_on_edge(abs_point, (0, 0, size[0], size[1])): if range < 20: # this is recurence call. When we are here it means that # side is longer then expected by over 2 times - it is not # the side we are looking for- corner is not valid return None else: return self.find_better_point(from_, abs_point, predicted_length * 2, 5) return abs_point