我们从Python开源项目中,提取了以下24个代码示例,用于说明如何使用cv2.perspectiveTransform()。
def bf_knnmatches( matches, img, kp1, kp2): MIN_MATCH_COUNT = 10 # store all the good matches as per Lowe's ratio test. good = [] dst = [] if len(matches[0]) == 2: for m, n in matches: if m.distance < 0.7*n.distance: good.append(m) if len(good) > MIN_MATCH_COUNT: src_pts = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1, 1, 2) dst_pts = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1, 1, 2) M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0) if M is not None: h, w = img.shape pts = np.float32([[0, 0], [0, h-1], [w-1, h-1], [w-1, 0]]).reshape(-1, 1, 2) dst = cv2.perspectiveTransform(pts, M) else: dst = [] else: dst = [] return dst
def draw_markers(img,markers): for m in markers: centroid = np.array(m['centroid'],dtype=np.float32) origin = np.array(m['verts'][0],dtype=np.float32) hat = np.array([[[0,0],[0,1],[.5,1.25],[1,1],[1,0]]],dtype=np.float32) hat = cv2.perspectiveTransform(hat,m_marker_to_screen(m)) if m['id_confidence']>.9: cv2.polylines(img,np.int0(hat),color = (0,0,255),isClosed=True) else: cv2.polylines(img,np.int0(hat),color = (0,255,0),isClosed=True) # cv2.polylines(img,np.int0(centroid),color = (255,255,int(255*m['id_confidence'])),isClosed=True,thickness=2) m_str = 'id: {:d}'.format(m['id']) org = origin.copy() # cv2.rectangle(img, tuple(np.int0(org+(-5,-13))[0,:]), tuple(np.int0(org+(100,30))[0,:]),color=(0,0,0),thickness=-1) cv2.putText(img,m_str,tuple(np.int0(org)[0,:]),fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=0.4, color=(0,0,255)) if 'id_confidence' in m: m_str = 'idc: {:.3f}'.format(m['id_confidence']) org += (0, 12) cv2.putText(img,m_str,tuple(np.int0(org)[0,:]),fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=0.4, color=(0,0,255)) if 'loc_confidence' in m: m_str = 'locc: {:.3f}'.format(m['loc_confidence']) org += (0, 12 ) cv2.putText(img,m_str,tuple(np.int0(org)[0,:]),fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=0.4, color=(0,0,255)) if 'frames_since_true_detection' in m: m_str = 'otf: {}'.format(m['frames_since_true_detection']) org += (0, 12 ) cv2.putText(img,m_str,tuple(np.int0(org)[0,:]),fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=0.4, color=(0,0,255)) if 'opf_vel' in m: m_str = 'otf: {}'.format(m['opf_vel']) org += (0, 12 ) cv2.putText(img,m_str,tuple(np.int0(org)[0,:]),fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=0.4, color=(0,0,255))
def visualize_homo(img1, img2, kp1, kp2, matches, homo, mask): h, w, d = img1.shape pts = [[0, 0], [0, h - 1], [w - 1, h - 1], [w - 1, 0]] pts = np.array(pts, dtype=np.float32).reshape((-1, 1, 2)) dst = cv.perspectiveTransform(pts, homo) img2 = cv.polylines(img2, [np.int32(dst)], True, [255, 0, 0], 3, 8) matches_mask = mask.ravel().tolist() draw_params = dict(matchesMask=matches_mask, singlePointColor=None, matchColor=(0, 255, 0), flags=2) res = cv.drawMatches(img1, kp1, img2, kp2, matches, None, **draw_params) return res
def get_mode_toggle(self,pos,img_shape): if self.detected and self.defined: x,y = pos frame = np.array([[[0,0],[1,0],[1,1],[0,1],[0,0]]],dtype=np.float32) frame = cv2.perspectiveTransform(frame,self.m_to_screen) text_anchor = frame.reshape((5,-1))[2] text_anchor[1] = 1-text_anchor[1] text_anchor *=img_shape[1],img_shape[0] text_anchor = text_anchor[0],text_anchor[1]-75 surface_edit_anchor = text_anchor[0],text_anchor[1]+25 marker_edit_anchor = text_anchor[0],text_anchor[1]+50 if np.sqrt((x-surface_edit_anchor[0])**2 + (y-surface_edit_anchor[1])**2) <15: return 'surface_mode' elif np.sqrt((x-marker_edit_anchor[0])**2 + (y-marker_edit_anchor[1])**2) <15: return 'marker_mode' else: return None else: return None
def get_full_flow(u_res,v_res,H,x=None,y=None,shape=None): """ Adds homography back into flow Parameters: x,y,u,v,H """ if (shape is None) and (x is None or y is None): print('Please provide either x/y or the shape.') if x is None and y is None: x,y = np.meshgrid(np.arange(shape[1]),np.arange(shape[0])) x2 = x + u_res y2 = y + v_res pt2_ = np.c_[x2.ravel(),y2.ravel()].astype('float32') pt1_ = np.c_[x.ravel(),y.ravel()].astype('float32') uv_ = cv2.perspectiveTransform(pt2_[:,np.newaxis,:],H).squeeze() - pt1_ return uv_[:,0].reshape(x.shape), uv_[:,1].reshape(x.shape)
def checkAvailability(sift, tkp, tdes, matchimg): """ :param sift: :param tkp: :param tdes:sift feature object, template keypoints, and template descriptor :param matchimg: :return: """ qimg = cv2.imread(matchimg) qimggray = cv2.cvtColor(qimg,cv2.COLOR_BGR2GRAY) # kernel = np.ones((5,5), np.uint8) # qimggray = cv2.erode(qimggray, kernel, iterations=1) # ret,threshimg = cv2.threshold(qimggray,100,255,cv2.THRESH_BINARY) qkp,qdes = sift.detectAndCompute(qimggray, None) # plt.imshow(threshimg, 'gray'), plt.show() FLANN_INDEX_KDITREE=0 index_params=dict(algorithm=FLANN_INDEX_KDITREE,tree=5) # FLANN_INDEX_LSH = 6 # index_params = dict(algorithm=FLANN_INDEX_LSH, # table_number=12, # 12 # key_size=20, # 20 # multi_probe_level=2) # 2 search_params = dict(checks = 50) flann=cv2.FlannBasedMatcher(index_params,search_params) matches=flann.knnMatch(tdes,qdes,k=2) goodMatch=[] for m_n in matches: if len(m_n) != 2: continue m, n = m_n if(m.distance<0.75*n.distance): goodMatch.append(m) MIN_MATCH_COUNT = 30 if (len(goodMatch) >= MIN_MATCH_COUNT): tp = [] qp = [] for m in goodMatch: tp.append(tkp[m.queryIdx].pt) qp.append(qkp[m.trainIdx].pt) tp, qp = np.float32((tp, qp)) H, status = cv2.findHomography(tp, qp, cv2.RANSAC, 3.0) h = timg.shape[0] w = timg.shape[1] trainBorder = np.float32([[[0, 0], [0, h - 1], [w - 1, h - 1], [w - 1, 0]]]) queryBorder = cv2.perspectiveTransform(trainBorder, H) cv2.polylines(qimg, [np.int32(queryBorder)], True, (0, 255, 0), 5) cv2.imshow('result', qimg) plt.imshow(qimg, 'gray'), plt.show() return True else: print "Not Enough match found- %d/%d" % (len(goodMatch), MIN_MATCH_COUNT) return False # cv2.imshow('result', qimg) # if cv2.waitKey(10) == ord('q'): # cv2.destroyAllWindows()
def build_correspondance(self, visible_markers,camera_calibration,min_marker_perimeter,min_id_confidence): """ - use all visible markers - fit a convex quadrangle around it - use quadrangle verts to establish perpective transform - map all markers into surface space - build up list of found markers and their uv coords """ all_verts = [m['verts'] for m in visible_markers if m['perimeter']>=min_marker_perimeter] if not all_verts: return all_verts = np.array(all_verts,dtype=np.float32) all_verts.shape = (-1,1,2) # [vert,vert,vert,vert,vert...] with vert = [[r,c]] # all_verts_undistorted_normalized centered in img center flipped in y and range [-1,1] all_verts_undistorted_normalized = cv2.undistortPoints(all_verts, camera_calibration['camera_matrix'],camera_calibration['dist_coefs']*self.use_distortion) hull = cv2.convexHull(all_verts_undistorted_normalized,clockwise=False) #simplify until we have excatly 4 verts if hull.shape[0]>4: new_hull = cv2.approxPolyDP(hull,epsilon=1,closed=True) if new_hull.shape[0]>=4: hull = new_hull if hull.shape[0]>4: curvature = abs(GetAnglesPolyline(hull,closed=True)) most_acute_4_threshold = sorted(curvature)[3] hull = hull[curvature<=most_acute_4_threshold] # all_verts_undistorted_normalized space is flipped in y. # we need to change the order of the hull vertecies hull = hull[[1,0,3,2],:,:] # now we need to roll the hull verts until we have the right orientation: # all_verts_undistorted_normalized space has its origin at the image center. # adding 1 to the coordinates puts the origin at the top left. distance_to_top_left = np.sqrt((hull[:,:,0]+1)**2+(hull[:,:,1]+1)**2) bot_left_idx = np.argmin(distance_to_top_left)+1 hull = np.roll(hull,-bot_left_idx,axis=0) #based on these 4 verts we calculate the transformations into a 0,0 1,1 square space m_from_undistored_norm_space = m_verts_from_screen(hull) self.detected = True # map the markers vertices into the surface space (one can think of these as texture coordinates u,v) marker_uv_coords = cv2.perspectiveTransform(all_verts_undistorted_normalized,m_from_undistored_norm_space) marker_uv_coords.shape = (-1,4,1,2) #[marker,marker...] marker = [ [[r,c]],[[r,c]] ] # build up a dict of discovered markers. Each with a history of uv coordinates for m,uv in zip (visible_markers,marker_uv_coords): try: self.markers[m['id']].add_uv_coords(uv) except KeyError: self.markers[m['id']] = Support_Marker(m['id']) self.markers[m['id']].add_uv_coords(uv) #average collection of uv correspondences accros detected markers self.build_up_status = sum([len(m.collected_uv_coords) for m in self.markers.values()])/float(len(self.markers)) if self.build_up_status >= self.required_build_up: self.finalize_correnspondance()
def img_to_ref_surface(self,pos): #convenience lines to allow 'simple' vectors (x,y) to be used shape = pos.shape pos.shape = (-1,1,2) new_pos = cv2.perspectiveTransform(pos,self.m_from_screen ) new_pos.shape = shape return new_pos
def ref_surface_to_img(self,pos): #convenience lines to allow 'simple' vectors (x,y) to be used shape = pos.shape pos.shape = (-1,1,2) new_pos = cv2.perspectiveTransform(pos,self.m_to_screen ) new_pos.shape = shape return new_pos
def map_datum_to_surface(d,m_from_screen): pos = np.array([d['norm_pos']]).reshape(1,1,2) mapped_pos = cv2.perspectiveTransform(pos , m_from_screen ) mapped_pos.shape = (2) on_srf = bool((0 <= mapped_pos[0] <= 1) and (0 <= mapped_pos[1] <= 1)) return {'topic':d['topic']+"_on_surface",'norm_pos':(mapped_pos[0],mapped_pos[1]),'confidence':d['confidence'],'on_srf':on_srf,'base_data':d }
def move_vertex(self,vert_idx,new_pos): """ this fn is used to manipulate the surface boundary (coordinate system) new_pos is in uv-space coords if we move one vertex of the surface we need to find the tranformation from old quadrangle to new quardangle and apply that transformation to our marker uv-coords """ before = marker_corners_norm after = before.copy() after[vert_idx] = new_pos transform = cv2.getPerspectiveTransform(after,before) for m in self.markers.values(): m.uv_coords = cv2.perspectiveTransform(m.uv_coords,transform)
def gl_draw_corners(self): """ draw surface and markers """ if self.detected: frame = cv2.perspectiveTransform(marker_corners_norm.reshape(-1,1,2),self.m_to_screen) draw_points_norm(frame.reshape((4,2)),20,RGBA(1.0,0.2,0.6,.5)) #### fns to draw surface in seperate window
def gl_display(self): """ Display marker and surface info inside world screen """ if self.mode == "Show Markers and Surfaces": for m in self.markers: hat = np.array([[[0,0],[0,1],[.5,1.3],[1,1],[1,0],[0,0]]],dtype=np.float32) hat = cv2.perspectiveTransform(hat,m_marker_to_screen(m)) if m['perimeter']>=self.min_marker_perimeter and m['id_confidence']>self.min_id_confidence: draw_polyline(hat.reshape((6,2)),color=RGBA(0.1,1.,1.,.5)) draw_polyline(hat.reshape((6,2)),color=RGBA(0.1,1.,1.,.3),line_type=GL_POLYGON) else: draw_polyline(hat.reshape((6,2)),color=RGBA(0.1,1.,1.,.5)) for s in self.surfaces: if s not in self.edit_surfaces and s is not self.marker_edit_surface: s.gl_draw_frame(self.img_shape) for s in self.edit_surfaces: s.gl_draw_frame(self.img_shape,highlight=True,surface_mode=True) s.gl_draw_corners() if self.marker_edit_surface: inc = [] exc = [] for m in self.markers: if m['perimeter']>=self.min_marker_perimeter: if m['id'] in self.marker_edit_surface.markers: inc.append(m['centroid']) else: exc.append(m['centroid']) draw_points(exc,size=20,color=RGBA(1.,0.5,0.5,.8)) draw_points(inc,size=20,color=RGBA(0.5,1.,0.5,.8)) self.marker_edit_surface.gl_draw_frame(self.img_shape,color=(0.0,0.9,0.6,1.0),highlight=True,marker_mode=True) for s in self.surfaces: if self.locate_3d: s.gl_display_in_window_3d(self.g_pool.image_tex,self.camera_calibration) else: s.gl_display_in_window(self.g_pool.image_tex)
def do_unwarp(self, where): """ do the opencv2 unwarp """ point = np.array([[where[0], where[1]]], dtype='float32') apoint = np.array([point]) turn = cv2.perspectiveTransform(apoint, self.map_matrix) return self.m_row_zero + (turn[0][0][1] * self.m_per_row)
def correctPoints(self, pts): if not self._homography_is_fixed: self._homography = None h = self._homography if pts.ndim == 2: pts = pts.reshape(1, *pts.shape) return cv2.perspectiveTransform(pts.astype(np.float32), h)
def quadFromH(self): sy, sx = self.img.shape[:2] # image edges: objP = np.array([[ [0, 0], [sx, 0], [sx, sy], [0, sy], ]], dtype=np.float32) return cv2.perspectiveTransform(objP, self._Hinv)
def windowToFieldCoordinates(basePoint, x1, y1, x2, y2, x3, y3, x4, y4, maxWidth=0, maxHeight=0): (xp, yp) = basePoint src = np.array([ [x1, y1], [x2, y2], [x3, y3], [x4, y4]], dtype = "float32") # those should be the same aspect as the real width/height of field maxWidth = (x4-x1) if maxWidth == 0 else maxWidth maxHeight = (y1-y2) if maxHeight == 0 else maxHeight # make a destination rectangle with the width and height of above (starts at 0,0) dst = np.array([ [0, 0], [maxWidth - 1, 0], [maxWidth - 1, maxHeight - 1], [0, maxHeight - 1]], dtype = "float32") # find the transformation matrix for our transforms transformationMatrix = cv2.getPerspectiveTransform(src, dst) # put the original (source) x,y points in an array (not sure why do we have to put it 3 times though) original = np.array([((xp, yp), (xp, yp), (xp, yp))], dtype=np.float32) # use perspectiveTransform to transform our original(mouse coords) to new coords with the transformation matrix transformed = cv2.perspectiveTransform(original, transformationMatrix)[0][0] return transformed
def get_residual_flow(x,y,u,v,H): """ Removes homography from flow Parameters: x,y,u,v,H. """ x2 = x + u y2 = y + v pt2_ = np.c_[x2.ravel(),y2.ravel()].astype('float32') pt1_ = np.c_[x.ravel(),y.ravel()].astype('float32') Hinv = np.linalg.inv(H) uv_ = cv2.perspectiveTransform(pt2_[:,np.newaxis,:],Hinv).squeeze() - pt1_ return uv_[:,0].reshape(x.shape), uv_[:,1].reshape(x.shape)
def homography2flow(x,y,H): """ Convert homography to flow field """ pt1_ = np.c_[x.ravel(),y.ravel()].astype('float32') uv = cv2.perspectiveTransform(pt1_[:,np.newaxis,:],H).squeeze() - pt1_ return uv[:,0].reshape(x.shape), uv[:,1].reshape(x.shape)
def ptransform(xy, M): """ Just a small wrapper to cv2.perspectiveTransform """ if xy.shape[1] == 2: return cv2.perspectiveTransform(xy[:,np.newaxis,:], M).squeeze() else: return cv2.perspectiveTransform(xy.T[:,np.newaxis,:], M).squeeze().T
def gl_draw_frame(self,img_size,color = (1.0,0.2,0.6,1.0),highlight=False,surface_mode=False,marker_mode=False): """ draw surface and markers """ if self.detected: r,g,b,a = color frame = np.array([[[0,0],[1,0],[1,1],[0,1],[0,0]]],dtype=np.float32) hat = np.array([[[.3,.7],[.7,.7],[.5,.9],[.3,.7]]],dtype=np.float32) hat = cv2.perspectiveTransform(hat,self.m_to_screen) frame = cv2.perspectiveTransform(frame,self.m_to_screen) alpha = min(1,self.build_up_status/self.required_build_up) if highlight: draw_polyline_norm(frame.reshape((5,2)),1,RGBA(r,g,b,a*.1),line_type=GL_POLYGON) draw_polyline_norm(frame.reshape((5,2)),1,RGBA(r,g,b,a*alpha)) draw_polyline_norm(hat.reshape((4,2)),1,RGBA(r,g,b,a*alpha)) text_anchor = frame.reshape((5,-1))[2] text_anchor[1] = 1-text_anchor[1] text_anchor *=img_size[1],img_size[0] text_anchor = text_anchor[0],text_anchor[1]-75 surface_edit_anchor = text_anchor[0],text_anchor[1]+25 marker_edit_anchor = text_anchor[0],text_anchor[1]+50 if self.defined: if marker_mode: draw_points([marker_edit_anchor],color=RGBA(0,.8,.7)) else: draw_points([marker_edit_anchor]) if surface_mode: draw_points([surface_edit_anchor],color=RGBA(0,.8,.7)) else: draw_points([surface_edit_anchor]) self.glfont.set_blur(3.9) self.glfont.set_color_float((0,0,0,.8)) self.glfont.draw_text(text_anchor[0]+15,text_anchor[1]+6,self.marker_status()) self.glfont.draw_text(surface_edit_anchor[0]+15,surface_edit_anchor[1]+6,'edit surface') self.glfont.draw_text(marker_edit_anchor[0]+15,marker_edit_anchor[1]+6,'add/remove markers') self.glfont.set_blur(0.0) self.glfont.set_color_float((0.1,8.,8.,.9)) self.glfont.draw_text(text_anchor[0]+15,text_anchor[1]+6,self.marker_status()) self.glfont.draw_text(surface_edit_anchor[0]+15,surface_edit_anchor[1]+6,'edit surface') self.glfont.draw_text(marker_edit_anchor[0]+15,marker_edit_anchor[1]+6,'add/remove markers') else: progress = (self.build_up_status/float(self.required_build_up))*100 progress_text = '%.0f%%'%progress self.glfont.set_blur(3.9) self.glfont.set_color_float((0,0,0,.8)) self.glfont.draw_text(text_anchor[0]+15,text_anchor[1]+6,self.marker_status()) self.glfont.draw_text(surface_edit_anchor[0]+15,surface_edit_anchor[1]+6,'Learning affiliated markers...') self.glfont.draw_text(marker_edit_anchor[0]+15,marker_edit_anchor[1]+6,progress_text) self.glfont.set_blur(0.0) self.glfont.set_color_float((0.1,8.,8.,.9)) self.glfont.draw_text(text_anchor[0]+15,text_anchor[1]+6,self.marker_status()) self.glfont.draw_text(surface_edit_anchor[0]+15,surface_edit_anchor[1]+6,'Learning affiliated markers...') self.glfont.draw_text(marker_edit_anchor[0]+15,marker_edit_anchor[1]+6,progress_text)
def getMatches(self, sceneImage): """ sceneImage: ?????array?? return dst: ???????? """ # Initiate SIFT detector sift = cv2.xfeatures2d.SIFT_create() # find the keypoints and descriptors with SIFT kp1, des1 = sift.detectAndCompute(self.MarkImage[:,:,0],None) kp2, des2 = sift.detectAndCompute(sceneImage[:,:,0],None) # create BFMatcher object FLANN_INDEX_KDTREE = 0 index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5) search_params = dict(checks = 50) flann = cv2.FlannBasedMatcher(index_params, search_params) # Match descriptors. matches = flann.knnMatch(des1,des2,k=2) # Sort them in the order of their distance. good = [] for m,n in matches: if m.distance < 0.7*n.distance: good.append(m) if len(good) < self.MIN_MATCH_COUNT: return None src_pts = np.float32([ kp1[m.queryIdx].pt for m in good ]).reshape(-1,1,2) dst_pts = np.float32([ kp2[m.trainIdx].pt for m in good ]).reshape(-1,1,2) M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC,5.0) matchesMask = mask.ravel().tolist() h,w = self.MarkImage.shape[:2] pts = np.float32([ [0,0],[0,h-1],[w-1,h-1],[w-1,0] ]).reshape(-1,1,2) dst = cv2.perspectiveTransform(pts,M) draw_params = dict(matchColor = (0,255,0), # draw matches in green color singlePointColor = None, matchesMask = matchesMask, # draw only inliers flags = 2) self.SceneImage = sceneImage self.DrawParams = draw_params self.KP1 = kp1 self.KP2 = kp2 self.GoodMatches = good return dst
def matchFeatures(queryFeature, trainFeature, matcher): """ match(...) function: match query image features and train image features. parameter: queryFeature: features of query image trainFeature: features of train image matcher: feature matcher queryImage: this is just for test to show the position of the found image which in the query image , input query image data which has processed by cv2.imread(). return: if found matched image ,return image name, otherwise return None. """ queryKeypoints = queryFeature[0] queryDescriptors = queryFeature[1] trainKeypoints = trainFeature[0] trainDescriptors = trainFeature[1] trainImgSize = trainFeature[2] trainImgHeight = trainImgSize[0] trainImgWidth = trainImgSize[1] corners=numpy.float32([[0, 0], [trainImgWidth, 0], [trainImgWidth, trainImgHeight], [0, trainImgHeight]]) raw_matches = matcher.knnMatch(trainDescriptors, queryDescriptors, 2) queryGoodPoints, trainGoodPoints = filter_matches(trainKeypoints, queryKeypoints, raw_matches) if len(queryGoodPoints) >= 4: H,status = cv2.findHomography(queryGoodPoints, trainGoodPoints, cv2.RANSAC, 5.0) else: H,status = None,None res=False obj_corners=None if H is not None: corners = corners.reshape(1, -1, 2) obj_corners = numpy.int32(cv2.perspectiveTransform(corners, H).reshape(-1, 2)) is_polygon = ispolygon(obj_corners) if is_polygon: res=True del queryKeypoints del queryDescriptors del trainKeypoints del trainDescriptors del trainImgSize del corners del raw_matches del queryGoodPoints del trainGoodPoints del obj_corners return res