Exemple #1
0
    def update_image2(self): #updates images with boid locations and responsibility vectors
        self.reset_image()
        
        if (self.debug_mode):
            debug_colors = [[255, 50, 50], [50, 255, 50], [50, 50, 255]]
            for boid in self.world.boids:
                poly = self.create_boid_poly([boid.location.y, boid.location.x], boid.theta)#create boid polygon in world coord
                #print poly
                poly = np.float32([ poly ]).reshape(-1,1,2)
                
                for i in range(self.num_proj):
                    boid_pix = cv2.perspectiveTransform(poly, self.homog[i])            
                    boid_pix = np.int32(boid_pix).reshape(1,-1,2)
                    cv2.fillConvexPoly(self.image[i], np.fliplr(boid_pix[0]), debug_colors[i])

        else:
            for boid in self.world.boids:
                poly = self.create_boid_poly([boid.location.y, boid.location.x], boid.theta)#create boid polygon in world coord
                
                #figure out which projector owns it
                proj_own = -1
                for i in range(self.num_proj):
                    if self.resp[i].contains(ShpPoint(boid.location.y, boid.location.x)):
                        proj_own = i
                        break
                        
                #transform to proj coordinates
                if (proj_own >= 0):
                    poly = np.float32([ poly ]).reshape(-1,1,2)
                    boid_pix = cv2.perspectiveTransform(poly, self.homog[proj_own])            
                    boid_pix = np.int32(boid_pix).reshape(1,-1,2)
                    cv2.fillConvexPoly(self.image[proj_own], np.fliplr(boid_pix[0]), boid.color)

        self.draw()
Exemple #2
0
    def lk_assest(self):
        # If we have to few assest points, we recompute them (FIXME:
        # magic constants)
        if self.lk_assest_points is None or len(self.lk_assest_points) < 10:
            self.lk_assest_points = self.get_lk_points(self.ref_image, self.ref_table_points, self.lk_assest_points)

        # Warp reference frame to put in the same position as the
        # previously known corner points (FIXME: magic constants)
        detection_settings = self.settings.detection_settings
        H = cv2.getPerspectiveTransform(detection_settings.ref_table_points.reshape(-1, 1, 2), self.prev.table_points)
        warped_ref_image = cv2.warpPerspective(self.ref_image, H, (320, 240))
        self.controls.show("warped", warped_ref_image / 256.0)
        p0 = cv2.perspectiveTransform(self.lk_assest_points, H)

        begin_frame = warped_ref_image
        end_frame = self.frame

        begin_points, end_points = self.lk_flow(p0=p0, begin_frame=begin_frame, end_frame=end_frame)
        self.lk_assest_points = cv2.perspectiveTransform(numpy.array(begin_points), numpy.linalg.inv(H))

        # self.draw_frame_with_points(begin_frame, p0, "assest points before", begin_points)
        # self.draw_frame_with_points(end_frame, end_points, "assest points after", end_points)

        begin_ref = self.lk_assest_points
        end_ref = numpy.array(end_points)
        return self.project_along(begin_ref, end_ref, self.ref_table_points.reshape(-1, 1, 2))
Exemple #3
0
    def gl_draw_frame(self,img_size):
        """
        draw surface and markers
        """
        if self.detected:
            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)
            draw_polyline_norm(frame.reshape((5,2)),1,RGBA(1.0,0.2,0.6,alpha))
            draw_polyline_norm(hat.reshape((4,2)),1,RGBA(1.0,0.2,0.6,alpha))

            #grid = frame.reshape((5,2))
            # self.crop_region = np.array([
            #     [grid[0][0] * img_size[1], grid[0][1] * img_size[0]],
            #     [grid[1][0] * img_size[1], grid[1][1] * img_size[0]],
            #     [grid[2][0] * img_size[1], grid[2][1] * img_size[0]],
            #     [grid[3][0] * img_size[1], grid[3][1] * img_size[0]]],
            #     dtype=np.float32)

            draw_points_norm(frame.reshape((5,-1))[0:1])
            text_anchor = frame.reshape((5,-1))[2]
            text_anchor[1] = 1-text_anchor[1]
            text_anchor *=img_size[1],img_size[0]
            self.glfont.draw_text(text_anchor[0],text_anchor[1],self.marker_status())
def output_perspective_transform(img_object, M):
    h,w = img_object.shape
    corner_pts = np.float32([ [0,0],[0,h-1],[w-1,h-1],[w-1,0] ]).reshape(-1,1,2)
    center_pts = np.float32([ [w/2,h/2] ]).reshape(-1,1,2)
    corner_pts_3d = np.float32([ [-w/2,-h/2,0],[-w/2,(h-1)/2,0],[(w-1)/2,(h-1)/2,0],[(w-1)/2,-h/2,0] ])###
    corner_camera_coord = cv2.perspectiveTransform(corner_pts,M)###
    center_camera_coord = cv2.perspectiveTransform(center_pts,M)
    return corner_camera_coord, center_camera_coord, corner_pts_3d, center_pts
Exemple #5
0
    def _update_definition(self, idx, visible_markers, camera_model):
        if not visible_markers:
            return

        all_verts_dist = np.array(
            [m.verts_px for m in visible_markers.values()], dtype=np.float32
        )
        all_verts_dist.shape = (-1, 2)
        all_verts_undist = camera_model.undistortPoints(all_verts_dist)

        hull_undist = self._bounding_quadrangle(all_verts_undist)
        undist_img_to_surf_trans_candidate = self._get_trans_to_norm_corners(
            hull_undist
        )
        all_verts_undist.shape = (-1, 1, 2)
        marker_surf_coords_undist = cv2.perspectiveTransform(
            all_verts_undist, undist_img_to_surf_trans_candidate
        )

        hull_dist = self._bounding_quadrangle(all_verts_dist)
        dist_img_to_surf_trans_candidate = self._get_trans_to_norm_corners(hull_dist)
        all_verts_dist.shape = (-1, 1, 2)
        marker_surf_coords_dist = cv2.perspectiveTransform(
            all_verts_dist, dist_img_to_surf_trans_candidate
        )

        # Reshape to [marker, marker...]
        # where marker = [[u1, v1], [u2, v2], [u3, v3], [u4, v4]]
        marker_surf_coords_undist.shape = (-1, 4, 2)
        marker_surf_coords_dist.shape = (-1, 4, 2)

        # Add observations to library
        for marker, uv_undist, uv_dist in zip(
            visible_markers.values(), marker_surf_coords_undist, marker_surf_coords_dist
        ):
            try:
                self.registered_markers_undist[marker.id].add_observation(uv_undist)
                self.registered_markers_dist[marker.id].add_observation(uv_dist)
            except KeyError:
                self.registered_markers_undist[marker.id] = Surface_Marker_Aggregate(
                    marker.id
                )
                self.registered_markers_undist[marker.id].add_observation(uv_undist)
                self.registered_markers_dist[marker.id] = Surface_Marker_Aggregate(
                    marker.id
                )
                self.registered_markers_dist[marker.id].add_observation(uv_dist)

        num_observations = sum(
            [len(m.observations) for m in self.registered_markers_undist.values()]
        )
        self._avg_obs_per_marker = num_observations / len(
            self.registered_markers_undist
        )
        self.build_up_status = self._avg_obs_per_marker / self._REQUIRED_OBS_PER_MARKER

        if self.build_up_status >= 1:
            self.prune_markers()
def distance_finder(frame, lines = None, fallas = None):

    if lines != None:
        # Variables importantes
        distaciaFocal = 1286    #1286.07
        largoEntreLineas = 25   #cm
        altura_camara = 11.2 #cm

        # Variables menos importantes
        height = frame.shape[0]
        width = frame.shape[1]

        #Desempacamos
        [lineaIzq,lineaDer] = lines

        ### Ahora viene el calculo de lineas paralelas ###

        # Primero calculamos los cuatro puntos limites de las lineas electricas.
        rectOriginal = np.float32(perspective_bound(frame, [lineaIzq,lineaDer]))
        # Ahora definimos los limites de la nueva imagen
        rectPerspective = np.float32([[0,0], [height,0], [0,height], [height,height]])
        # Calculamos la matriz de perspectiva
        if lineaIzq == None:
            frame_perspective = np.zeros((height,height,3))
        else:
            M = cv2.getPerspectiveTransform(rectOriginal,rectPerspective)
            # Transformamos la imagen para ver como queda
            frame_perspective = cv2.warpPerspective(frame,M, (height,height))

            # #Iteramos sobre todos los puntos que encontramos para encontrar su paralela
            for color in fallas:
                for centro in fallas[color]:
                    #Transformamos el centroide del
                    centro_perspectiva = cv2.perspectiveTransform(np.array([[centro[0]]],dtype = 'float32'),M)    #Los puntos que le entran a la funcion perspectiveTransform, tienen que ser de la forma [[[x1,y1],[x2,y2, ...]]], con ESA cantidad de parentesis.
                    # Calculamos el mismo punto en la otra linea
                    centro_perspectiva = centro_perspectiva[0][0].copy()
                    if centro_perspectiva[0] < height/2:
                        punto_contrario_perspectiva = np.array([height, centro_perspectiva[1]])
                    else:
                        punto_contrario_perspectiva = np.array([0, centro_perspectiva[1]], dtype = 'float')
                    # Destransformamos el punto
                    # print "M = {}".format(M)
                    # print "invM = {}".format(cv2.invert(M))
                    punto_contrario = cv2.perspectiveTransform(np.array([[punto_contrario_perspectiva]],dtype = 'float32'),cv2.invert(M)[1])
                    # Graficamos, las lineas que encontramos
                    punto_contrario = punto_contrario[0][0].copy()
                    cv2.line(frame,tuple(centro[0]),tuple(punto_contrario),coloresDibujo['azul'],2)
                    # Calculamos la distancia en pixeles
                    distPixeles = np.sqrt(np.square(centro[0][0] - punto_contrario[0]) + np.square(centro[0][1] - punto_contrario[1]))
                    # Usamos la ecuacion de similitud triangular para sacar la distancia
                    distCamara = largoEntreLineas*distaciaFocal/distPixeles
                    # Ahora usamos la relacion de pitagoras para calcular la distancia de la falla al chasis
                    distChasis = np.sqrt(np.square(distCamara) - np.square(altura_camara))
                    # guardamos la distancia en centimetros en el diccionario de fallas

                    centro[1] = distChasis

            return fallas
 def get_distance(self, datapoint):
     if self._homo is not None  and datapoint.get_homo() is not None:
         des = cv2.perspectiveTransform(self._cor, self._homo)
         desn = cv2.perspectiveTransform(self._cor, datapoint.get_homo())
         dist = 0.
         for p1,p2 in zip(des[0], desn[0]):
             dist += abs(p1[0] - p2[0]) + abs(p1[1] - p2[1])
         return dist
     else:
         return None
Exemple #8
0
    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 gl_draw_frame(self):
     """
     draw surface and markers
     """
     if self.detected:
         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)
         draw_gl_polyline_norm(frame.reshape((5,2)),(1.0,0.2,0.6,alpha))
         draw_gl_polyline_norm(hat.reshape((4,2)),(1.0,0.2,0.6,alpha))
 def get_middle(self, other):
     nhomo = None
     if self._homo is not None  and other.get_homo() is not None:
         des = cv2.perspectiveTransform(self._cor, self._homo)
         desn = cv2.perspectiveTransform(self._cor, other.get_homo())
         new_cor = []
         for p1,p2 in zip(des[0], desn[0]):
             new_cor.append([(p1[0] + p2[0])/2, (p1[1] + p2[1])/2])
         new_cor = np.array(new_cor,dtype='float32')
         new_cor = np.array([new_cor])
         old_cor = self._cor
         nhomo, mask = cv2.findHomography(old_cor, new_cor, cv2.RANSAC)
     return DataPoint(self._method + "mid" + other._method, self._shape, self._quality * other._quality, nhomo)
    def gl_display(self):
        """
        Display marker and surface info inside world screen
        """
        if self.mode == "Show markers and frames":
            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))
                draw_gl_polyline(hat.reshape((6,2)),(0.1,1.,1.,.5))

            for s in self.surfaces:
                s.gl_draw_frame(self.img_shape)


        for s in self.surfaces:
            if self.locate_3d:
                s.gl_display_in_window_3d(self.g_pool.image_tex,self.camera_intrinsics)
            else:
                s.gl_display_in_window(self.g_pool.image_tex)


        if self.mode == "Surface edit mode":
            for s in self.surfaces:
                s.gl_draw_frame(self.img_shape)
                s.gl_draw_corners()
 def process(self):
     img1 = cv2.cvtColor(self.imgcv1, cv2.COLOR_BGR2GRAY)  #queryimage # left image
     img2 = cv2.cvtColor(self.imgcv2, cv2.COLOR_BGR2GRAY)  #trainimage # right image
     # find the keypoints and descriptors with SIFT
     kp1, des1 = self.detector.detectAndCompute(img1,None)
     kp2, des2 = self.detector.detectAndCompute(img2,None)      
     matches = self.flann.knnMatch(des1,des2,k=2)       
     pts1 = []
     pts2 = []        
     # ratio test as per Lowe's paper
     for i,(m,n) in enumerate(matches):
         if m.distance < 0.8*n.distance:
             pts2.append(kp2[m.trainIdx].pt)
             pts1.append(kp1[m.queryIdx].pt)
     pts1 = np.float32(pts1)
     pts2 = np.float32(pts2)
     M, mask = cv2.findHomography(pts1, pts2, cv2.RANSAC,5.0)
     h,w = img1.shape
     h/=2
     w/=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)
     cv2.polylines(img2,[np.int32(dst)],True,255,3)
     #We select only inlier points
     pts1 = pts1[mask.ravel()==1]
     pts2 = pts2[mask.ravel()==1]
     self.data=(M,pts1,pts2)
     pts1i=np.int32(pts1)
     pts2i=np.int32(pts2)
     return drawpoints(img1,img2,pts1i,pts2i)
def reconstruct_thumbnail(thumbnail_image, source_image, kp_pairs, H, downsize_reconstruction=False):
    logging.info("Reconstructing thumbnail from source image")

    thumb_h, thumb_w = thumbnail_image.shape[:2]
    source_h, source_w = source_image.shape[:2]

    corners = numpy.float32([[0, 0], [thumb_w, 0], [thumb_w, thumb_h], [0, thumb_h]])
    corners = numpy.int32(cv2.perspectiveTransform(corners.reshape(1, -1, 2), H).reshape(-1, 2))

    logging.info("Thumbnail bounds within source image: %s", corners.tolist())

    corners_x, corners_y = zip(*corners.tolist())

    new_thumb_crop = ((min(corners_y), max(corners_y)), (min(corners_x), max(corners_x)))

    new_thumb = source_image[slice(*new_thumb_crop[0]), slice(*new_thumb_crop[1])]

    new_thumb_rotation, new_thumb = autorotate_image(new_thumb, corners)

    new_thumb_h, new_thumb_w = new_thumb.shape[:2]

    if downsize_reconstruction and (new_thumb_h > thumb_h or new_thumb_w > thumb_w):
        new_thumb = fit_image_within(new_thumb, thumb_h, thumb_w)

    logging.info("Master dimensions: %s", source_image.shape)
    logging.info("Thumbnail dimensions: %s", thumbnail_image.shape)
    logging.info("Reconstructed thumb dimensions: %s (rotation=%d°)", new_thumb.shape, new_thumb_rotation)

    return new_thumb, new_thumb_crop, new_thumb_rotation
 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))
Exemple #15
0
    def track(self, frame):
        '''Returns a list of detected TrackedTarget objects'''
        self.frame_points, frame_descrs = self.detect_features(frame)
        if len(self.frame_points) < MIN_MATCH_COUNT:
            return []
        matches = self.matcher.knnMatch(frame_descrs, k = 2)
        matches = [m[0] for m in matches if len(m) == 2 and m[0].distance < m[1].distance * 0.75]
        if len(matches) < MIN_MATCH_COUNT:
            return []
        matches_by_id = [[] for _ in xrange(len(self.targets))]
        for m in matches:
            matches_by_id[m.imgIdx].append(m)
        tracked = []
        for imgIdx, matches in enumerate(matches_by_id):
            if len(matches) < MIN_MATCH_COUNT:
                continue
            target = self.targets[imgIdx]
            p0 = [target.keypoints[m.trainIdx].pt for m in matches]
            p1 = [self.frame_points[m.queryIdx].pt for m in matches]
            p0, p1 = np.float32((p0, p1))
            H, status = cv2.findHomography(p0, p1, cv2.RANSAC, 3.0)
            status = status.ravel() != 0
            if status.sum() < MIN_MATCH_COUNT:
                continue
            p0, p1 = p0[status], p1[status]

            x0, y0, x1, y1 = target.rect
            quad = np.float32([[x0, y0], [x1, y0], [x1, y1], [x0, y1]])
            quad = cv2.perspectiveTransform(quad.reshape(1, -1, 2), H).reshape(-1, 2)

            track = TrackedTarget(target=target, p0=p0, p1=p1, H=H, quad=quad)
            tracked.append(track)
        tracked.sort(key = lambda t: len(t.p0), reverse=True)
        return tracked
def matching(kp1,des1,img1,kp2_ext,des2_ext):

    global MIN_MATCH_COUNT

    kp2 = kp2_ext
    des2 = des2_ext

    if len(kp1) <= MIN_MATCH_COUNT*2 or len(kp2) <= MIN_MATCH_COUNT*2:
        return [], None


    #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)
    #matches = flann.knnMatch(des1,des2,k=2)

    global FEATURE_DETECTOR
    global CROSS_CHECK

    if FEATURE_DETECTOR == "AKAZE":
        if CROSS_CHECK:
            bf = cv2.BFMatcher(cv2.NORM_HAMMING,crossCheck=True)
            good = bf.match(des1,des2)
        else:
            bf = cv2.BFMatcher(cv2.NORM_HAMMING)
            matches = bf.knnMatch(des1, des2, k=2)
            good = []
            for m,n in matches:
                if m.distance < 0.8*n.distance:
                    good.append(m)
    else:
        if CROSS_CHECK:
            bf = cv2.BFMatcher(crossCheck=True)
            good = bf.match(des1,des2)
        else:
            bf = cv2.BFMatcher()
            matches = bf.knnMatch(des1, des2, k=2)
            good = []
            for m,n in matches:
                if m.distance < 0.8*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 mask is None:
            return [], None

        h,w = img1.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)

        return good, np.int32(dst)

    return [], None
def draw_match(img1, img2, p1, p2, status = None, H = None):
    h1, w1 = img1.shape[:2]
    h2, w2 = img2.shape[:2]
    vis = np.zeros((max(h1, h2), w1+w2), np.uint8)
    vis[:h1, :w1] = img1
    vis[:h2, w1:w1+w2] = img2
    vis = cv2.cvtColor(vis, cv2.COLOR_GRAY2BGR)

    if H is not None:
        corners = np.float32([[0, 0], [w1, 0], [w1, h1], [0, h1]])
        corners = np.int32( cv2.perspectiveTransform(corners.reshape(1, -1, 2), H).reshape(-1, 2) + (w1, 0) )
        cv2.polylines(vis, [corners], True, (255, 255, 255))
    
    if status is None:
        status = np.ones(len(p1), np.bool_)
    green = (0, 255, 0)
    red = (0, 0, 255)
    for (x1, y1), (x2, y2), inlier in zip(np.int32(p1), np.int32(p2), status):
        col = [red, green][inlier]
        if inlier:
            cv2.line(vis, (x1, y1), (x2+w1, y2), col)
            cv2.circle(vis, (x1, y1), 2, col, -1)
            cv2.circle(vis, (x2+w1, y2), 2, col, -1)
        else:
            r = 2
            thickness = 3
            cv2.line(vis, (x1-r, y1-r), (x1+r, y1+r), col, thickness)
            cv2.line(vis, (x1-r, y1+r), (x1+r, y1-r), col, thickness)
            cv2.line(vis, (x2+w1-r, y2-r), (x2+w1+r, y2+r), col, thickness)
            cv2.line(vis, (x2+w1-r, y2+r), (x2+w1+r, y2-r), col, thickness)
    return vis
    def build_correspondance(self, visible_markers,camera_calibration,min_marker_perimeter):
        """
        - 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)
        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'])
        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 in to 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 _calculate_hat_points(self, marker_points):
     perspective_matrix = cv2.getPerspectiveTransform(
         self._square_definition, marker_points
     )
     hat_points = cv2.perspectiveTransform(self._hat_definition, perspective_matrix)
     hat_points.shape = 6, 2
     return hat_points
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 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))
Exemple #22
0
    def gl_display(self):
        """
        Display marker and surface info inside world screen
        """

        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))
            draw_gl_polyline(hat.reshape((6,2)),(0.1,1.,1.,.5))

        for s in  self.surfaces:
            s.gl_draw_frame()

        if self.surface_edit_mode.value:
            for s in  self.surfaces:
                s.gl_draw_corners()


        if self._window and self.surfaces:
            try:
                s = self.surfaces[self.show_surface_idx.value]
            except IndexError:
                s = None
            if s and s.detected:
                self.gl_display_in_window(s)
def warpImagePair(image_1, image_2, homography):
    warped_image = None
    x_min = 0
    y_min = 0
    x_max = 0
    y_max = 0

    image_1_corners = get_image_corners(image_1)
    image_2_corners = get_image_corners(image_2)

    image_1_corners = cv2.perspectiveTransform(image_1_corners, homography)
    corners = np.concatenate((image_1_corners, image_2_corners))

    x_min = min(corners[:, 0, 0])
    x_max = max(corners[:, 0, 0])
    y_min = min(corners[:, 0, 1])
    y_max = max(corners[:, 0, 1])

    translation_matrix = np.array([[1, 0, -1 * x_min], [0, 1, -1 * y_min], [0, 0, 1]])
    translated_homography = np.dot(translation_matrix, homography)

    warped_image_1 = cv2.warpPerspective(image_1, translated_homography, (x_max - x_min, y_max - y_min))

    # Select a sub-region of the warped image that matches image_2's (primary image's) coordinate frame
    warped_image_1 = warped_image_1[-y_min:-y_min+image_2.shape[0], -x_min:-x_min+image_2.shape[1]]

    return warped_image_1
Exemple #24
0
def calculate3DPosition(Point2D1, Point2D2):
    """
    Triangulate a 3D position from 2 2D position from camera
    and each camera projection matrix
    :param camera1:
    :param camera2:
    :param Point2D1:
    :param Point2D2:
    :return:
    """

    xy1 = [Point2D1.get()['x'], Point2D1.get()['y']]
    xy2 = [Point2D2.get()['x'], Point2D2.get()['y']]
#    print str(xy1) + " - " + str(Point2D1)
#    print str(xy2) + " - " + str(Point2D2)
    triangulationOutput = cv2.triangulatePoints(Point2D1.camera.projection_matrix,Point2D2.camera.projection_matrix, np.float32(xy1), np.float32(xy2))

    mypoint1 = np.array([triangulationOutput[0], triangulationOutput[1], triangulationOutput[2]])
    mypoint1 = mypoint1.reshape(-1, 3)
    mypoint1 = np.array([mypoint1])
    P_24x4 = np.resize(Point2D1.camera.projection_matrix[0], (4,4))
    P_24x4[3,0] = 0
    P_24x4[3,1] = 0
    P_24x4[3,2] = 0
    P_24x4[3,3] = 1

    projected = cv2.perspectiveTransform(mypoint1, P_24x4)
    output = triangulationOutput[:-1]/triangulationOutput[-1]
#    print output
    #TODO calculate point again with second proj mat, and calculate middle
    return output
    def _detect_corner_points(self, key_frame, good_matches):
        """Detects corner points in an input (query) image

            This method finds the homography matrix to go from the template
            (train) image to the input (query) image, and finds the coordinates
            of the good matches (from the train image) in the query image.

            :param key_frame: keypoints of the query image
            :param good_matches: list of good matches
            :returns: coordinates of good matches in transformed query image
        """
        # find homography using RANSAC
        src_points = [self.key_train[good_matches[i].queryIdx].pt
                      for i in xrange(len(good_matches))]
        dst_points = [key_frame[good_matches[i].trainIdx].pt
                      for i in xrange(len(good_matches))]
        H, _ = cv2.findHomography(np.array(src_points), np.array(dst_points),
                                  cv2.RANSAC)

        # outline train image in query image
        src_corners = np.array([(0, 0), (self.sh_train[1], 0),
                                (self.sh_train[1], self.sh_train[0]),
                                (0, self.sh_train[0])], dtype=np.float32)
        dst_corners = cv2.perspectiveTransform(src_corners[None, :, :], H)

        # convert to tuple
        dst_corners = map(tuple, dst_corners[0])
        return dst_corners
    def draw_matches(self, img, kp_pairs, status, H):
        '''Derived from find_obj.py'''
        
        vis = img

        h, w = self.feature_shape[:2]
        
        if H is not None:   
            corners = np.float32([[0, 0], [w, 0], [w, h], [0, h]]) + self.feature_offset
            corners = np.int32( cv2.perspectiveTransform(corners.reshape(1, -1, 2), H).reshape(-1, 2))
            cv2.polylines(vis, [corners], True, (255, 255, 255))
    
        if status is None:
            status = np.ones(len(kp_pairs), np.bool_)
            
        p2 = np.int32([kpp[1].pt for kpp in kp_pairs])
    
        green = (0, 255, 0)
        red = (0, 0, 255)
        
        for (x2, y2), inlier in zip(p2, status):
            if inlier:
                col = green
                cv2.circle(vis, (x2, y2), 2, col, -1)
            else:
                col = red
                r = 2
                thickness = 3
                cv2.line(vis, (x2-r, y2-r), (x2+r, y2+r), col, thickness)
                cv2.line(vis, (x2-r, y2+r), (x2+r, y2-r), col, thickness)
def find_homography(kp1, des1, kp2, des2):
    """
        Given a set of keypoints and descriptors finds the homography
    """
    # Tenta fazer a melhor comparacao usando o algoritmo
    matches = flann.knnMatch(des1, des2, k=2)

    # store all the good matches as per Lowe's ratio test.
    good = []
    for m,n in matches:
        if m.distance < 0.7*n.distance:
            good.append(m)

    if len(good)>MIN_MATCH_COUNT:
        # Separa os bons matches na origem e no destino
        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)


        # Tenta achar uma trasformacao composta de rotacao, translacao e escala que situe uma imagem na outra
        M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC,5.0)
        matchesMask = mask.ravel().tolist()

        h,w = img1.shape
        pts = np.float32([ [0,0],[0,h-1],[w-1,h-1],[w-1,0] ]).reshape(-1,1,2)

        # Transforma os pontos da imagem origem para onde estao na imagem destino
        dst = cv2.perspectiveTransform(pts,M)

        return M
    else:
        # Caso em que nao houve matches o suficiente
        return -1
	def handleTree(self, group):
		projectedCorners = group['projectedCorners']
		srcGroupMap = group['projectedPoints']
		groupColors = group['colors']
		groupColors.clear()

		image = cv2.imread("images/treeTexture.png", -1)
		height = image.shape[0]
		width = image.shape[1]

		src = self.verticalReshape(projectedCorners)
		dst = self.verticalReshape([(0, 0), (width, 0), (width, height), (0, height)])
		transformationMatrix, mask = cv2.findHomography(src, dst, cv2.RANSAC, 5.0)
		finalSrc = srcGroupMap.keys()
		finalDst = np.int32(cv2.perspectiveTransform(self.verticalReshape(finalSrc), 
																									transformationMatrix))
		for i in range(len(finalDst)):
				dstCoord = tuple(finalDst[i].ravel())
				if self.isOutOfFrame(dstCoord, width, height):
					continue
				colorWithAlpha = image[dstCoord[1]][dstCoord[0]]
				if(colorWithAlpha[3] < 1.0):
					color = np.asarray([-1, -1, -1])
				else:
					color = np.asarray([colorWithAlpha[0],
															colorWithAlpha[1],
															colorWithAlpha[2]])
				srcCoord = finalSrc[i]
				for point in srcGroupMap[srcCoord]:
					groupColors[tuple(point)] = color

		return
Exemple #29
0
def find_homography(kp1, des1, kp2, des2):
    """
        Given a set of keypoints and descriptors finds the homography
    """
    # Tenta fazer a melhor comparacao usando o algoritmo
    matches = flann.knnMatch(des1, des2, k=2)

    # store all the good matches as per Lowe's ratio test.
    good = []
    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)
        matchesMask = mask.ravel().tolist()

        h,w = img1.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)

        return M
    else:
        
        return -1
	def importExternalTextureFromImage(self, group, imageURL):
		projectedCorners = group['projectedCorners']
		srcGroupMap = group['projectedPoints']
		groupColors = group['colors']
		groupColors.clear()

		image = cv2.imread(imageURL, cv2.CV_LOAD_IMAGE_COLOR)
		height = image.shape[0]
		width = image.shape[1]

		src = self.verticalReshape(projectedCorners)
		dst = self.verticalReshape([(0, 0), (width, 0), (width, height), (0, height)])
		transformationMatrix, mask = cv2.findHomography(src, dst, cv2.RANSAC, 5.0)
		finalSrc = srcGroupMap.keys()
		finalDst = np.int32(cv2.perspectiveTransform(self.verticalReshape(finalSrc), 
																									transformationMatrix))
		for i in range(len(finalDst)):
				dstCoord = tuple(finalDst[i].ravel())
				if self.isOutOfFrame(dstCoord, width, height):
					continue
				srcCoord = finalSrc[i]
				for point in srcGroupMap[srcCoord]:
					groupColors[tuple(point)] = image[dstCoord[1]][dstCoord[0]]

		return
def mask_face(image, face_location, six_points, angle, args, type="surgical"):
    debug = False

    # Find the face angle
    threshold = 13
    if angle < -threshold:
        type += "_right"
    elif angle > threshold:
        type += "_left"

    face_height = face_location[2] - face_location[0]
    face_width = face_location[1] - face_location[3]
    # image = image_raw[
    #              face_location[0]-int(face_width/2): face_location[2]+int(face_width/2),
    #              face_location[3]-int(face_height/2): face_location[1]+int(face_height/2),
    #              :,
    #              ]
    # cv2.imshow('win', image)
    # cv2.waitKey(0)
    # Read appropriate mask image
    w = image.shape[0]
    h = image.shape[1]
    if not "empty" in type and not "inpaint" in type:
        cfg = read_cfg(config_filename="masks/masks.cfg", mask_type=type, verbose=False)
    else:
        if "left" in type:
            str = "surgical_blue_left"
        elif "right" in type:
            str = "surgical_blue_right"
        else:
            str = "surgical_blue"
        cfg = read_cfg(config_filename="masks/masks.cfg", mask_type=str, verbose=False)
    img = cv2.imread(cfg.template, cv2.IMREAD_UNCHANGED)

    # Process the mask if necessary
    if args.pattern:
        # Apply pattern to mask
        img = texture_the_mask(img, args.pattern, args.pattern_weight)

    if args.color:
        # Apply color to mask
        img = color_the_mask(img, args.color, args.color_weight)

    mask_line = np.float32(
        [cfg.mask_a, cfg.mask_b, cfg.mask_c, cfg.mask_f, cfg.mask_e, cfg.mask_d]
    )
    # Warp the mask
    M, mask = cv2.findHomography(mask_line, six_points)
    dst_mask = cv2.warpPerspective(img, M, (h, w))
    dst_mask_points = cv2.perspectiveTransform(mask_line.reshape(-1, 1, 2), M)
    mask = dst_mask[:, :, 3]
    face_height = face_location[2] - face_location[0]
    face_width = face_location[1] - face_location[3]
    image_face = image[
        face_location[0] + int(face_height / 2) : face_location[2],
        face_location[3] : face_location[1],
        :,
    ]

    image_face = image

    # Adjust Brightness
    mask_brightness = get_avg_brightness(img)
    img_brightness = get_avg_brightness(image_face)
    delta_b = 1 + (img_brightness - mask_brightness) / 255
    dst_mask = change_brightness(dst_mask, delta_b)

    # Adjust Saturation
    mask_saturation = get_avg_saturation(img)
    img_saturation = get_avg_saturation(image_face)
    delta_s = 1 - (img_saturation - mask_saturation) / 255
    dst_mask = change_saturation(dst_mask, delta_s)

    # Apply mask
    mask_inv = cv2.bitwise_not(mask)
    img_bg = cv2.bitwise_and(image, image, mask=mask_inv)
    img_fg = cv2.bitwise_and(dst_mask, dst_mask, mask=mask)
    out_img = cv2.add(img_bg, img_fg[:, :, 0:3])
    if "empty" in type or "inpaint" in type:
        out_img = img_bg
    # Plot key points

    if "inpaint" in type:
        out_img = cv2.inpaint(out_img, mask, 3, cv2.INPAINT_TELEA)
        # dst_NS = cv2.inpaint(img, mask, 3, cv2.INPAINT_NS)

    if debug:
        for i in six_points:
            cv2.circle(out_img, (i[0], i[1]), radius=4, color=(0, 0, 255), thickness=-1)

        for i in dst_mask_points:
            cv2.circle(
                out_img, (i[0][0], i[0][1]), radius=4, color=(0, 255, 0), thickness=-1
            )

    return out_img, mask
def processFile(filename):
  img = cv2.imread(filename)
  # img = scaleImageIfNeeded(img, 600, 480)
  img = scaleImageIfNeeded(img, 1024, 768)
  img_orig = img.copy()
  img_orig2 = img.copy()

  # Edges
  edges = cv2.Canny(img, 100, 550)

  # Get mask for where we think chessboard is
  mask, top_two_angles, min_area_rect, median_contour = getEstimatedChessboardMask(img, edges,iters=3) # More iters gives a finer mask
  print("Top two angles (in image coord system): %s" % top_two_angles)

  # Get hough lines of masked edges
  edges_masked = cv2.bitwise_and(edges,edges,mask = (mask > 0.5).astype(np.uint8))
  img_orig = cv2.bitwise_and(img_orig,img_orig,mask = (mask > 0.5).astype(np.uint8))

  lines = getHoughLines(edges_masked, min_line_size=0.25*min(min_area_rect[1]))
  print("Found %d lines." % len(lines))

  lines_a, lines_b = parseHoughLines(lines, top_two_angles, angle_threshold_deg=35)
  
  # plotHoughLines(img, lines, color=(255,255,255), line_thickness=1)
  # plotHoughLines(img, lines_a, color=(0,0,255))
  # plotHoughLines(img, lines_b, color=(0,255,0))
  if len(lines_a) < 2 or len(lines_b) < 2:
    return img_orig, edges_masked, img_orig

  a = time()
  for i2 in range(10):
    for i in range(100):
      corners = chooseRandomGoodQuad(lines_a, lines_b, median_contour)
      
      # warp_img, M = getTileImage(img_orig, corners.astype(np.float32),tile_buffer=16, tile_res=16)
      M = getTileTransform(corners.astype(np.float32),tile_buffer=16, tile_res=16)

      # Warp lines and draw them on warped image
      all_lines = np.vstack([lines_a[:,:2], lines_a[:,2:], lines_b[:,:2], lines_b[:,2:]]).astype(np.float32)
      warp_pts = cv2.perspectiveTransform(all_lines[None,:,:], M)
      warp_pts = warp_pts[0,:,:]
      warp_lines_a = np.hstack([warp_pts[:len(lines_a),:], warp_pts[len(lines_a):2*len(lines_a),:]])
      warp_lines_b = np.hstack([warp_pts[2*len(lines_a):2*len(lines_a)+len(lines_b),:], warp_pts[2*len(lines_a)+len(lines_b):,:]])


      # Get thetas of warped lines 
      thetas_a = np.array([getSegmentTheta(line) for line in warp_lines_a])
      thetas_b = np.array([getSegmentTheta(line) for line in warp_lines_b])
      median_theta_a = (np.median(thetas_a*180/np.pi))
      median_theta_b = (np.median(thetas_b*180/np.pi))
      
      # Gradually relax angle threshold over N iterations
      if i < 20:
        warp_angle_threshold = 0.03
      elif i < 30:
        warp_angle_threshold = 0.1
      elif i < 50:
        warp_angle_threshold = 0.3
      elif i < 70:
        warp_angle_threshold = 0.5
      elif i < 80:
        warp_angle_threshold = 1.0
      else:
        warp_angle_threshold = 2.0
      if ((angleCloseDeg(abs(median_theta_a), 0, warp_angle_threshold) and 
            angleCloseDeg(abs(median_theta_b), 90, warp_angle_threshold)) or 
          (angleCloseDeg(abs(median_theta_a), 90, warp_angle_threshold) and 
            angleCloseDeg(abs(median_theta_b), 0, warp_angle_threshold))):
        print('Found good match (%d): %.2f %.2f' % (i, abs(median_theta_a), abs(median_theta_b)))
        break
      # else:
      #   print('iter %d: %.2f %.2f' % (i, abs(median_theta_a), abs(median_theta_b)))

    warp_img, M = getTileImage(img_orig, corners.astype(np.float32),tile_buffer=16, tile_res=16)

    # Recalculate warp now that we're using a different tile_buffer/res
    # warp_pts = cv2.perspectiveTransform(all_lines[None,:,:], M)
    # warp_pts = warp_pts[0,:,:]
    # warp_lines_a = np.hstack([warp_pts[:len(lines_a),:], warp_pts[len(lines_a):2*len(lines_a),:]])
    # warp_lines_b = np.hstack([warp_pts[2*len(lines_a):2*len(lines_a)+len(lines_b),:], warp_pts[2*len(lines_a)+len(lines_b):,:]])
    
    lines_x, lines_y, step_x, step_y = getWarpCheckerLines(warp_img)
    if len(lines_x) > 0:
      print('Found good chess lines (%d): %s %s' % (i2, lines_x, lines_y))
      break
  print("Ransac corner detection took %.4f seconds." % (time() - a))

  print(lines_x, lines_y)
  warp_img, M = getTileImage(img_orig, corners.astype(np.float32),tile_buffer=16, tile_res=16)

  for corner in corners:
      cv2.circle(img, tuple(map(int,corner)), 5, (255,150,150),-1)  

  if len(lines_x) > 0:
    print('Found chessboard?')
    warp_corners, all_warp_corners = getRectChessCorners(lines_x, lines_y)
    tile_centers = all_warp_corners + np.array([step_x/2.0, step_y/2.0]) # Offset from corner to tile centers
    M_inv = np.matrix(np.linalg.inv(M))
    real_corners, all_real_tile_centers = getOrigChessCorners(warp_corners, tile_centers, M_inv)

    tile_res = 64 # Each tile has N pixels per side
    tile_buffer = 1
    warp_img, better_M = getTileImage(img_orig2, real_corners, tile_buffer=tile_buffer, tile_res=tile_res)
    # Further refine rectified image
    warp_img, was_rotated, refine_M = reRectifyImages(warp_img)
    # combined_M = better_M
    combined_M = np.matmul(refine_M,better_M)
    M_inv = np.matrix(np.linalg.inv(combined_M))

    # Get better_M based corners
    hlines = vlines = (np.arange(8)+tile_buffer)*tile_res
    hcorner = (np.array([0,8,8,0])+tile_buffer)*tile_res
    vcorner = (np.array([0,0,8,8])+tile_buffer)*tile_res
    ideal_corners = np.vstack([hcorner,vcorner]).T
    ideal_all_corners = np.array(list(itertools.product(hlines, vlines)))
    ideal_tile_centers = ideal_all_corners + np.array([tile_res/2.0, tile_res/2.0]) # Offset from corner to tile centers

    real_corners, all_real_tile_centers = getOrigChessCorners(ideal_corners, ideal_tile_centers, M_inv)
    
    # Get final refined rectified warped image for saving
    warp_img, _ = getTileImage(img_orig2, real_corners, tile_buffer=tile_buffer, tile_res=tile_res)

    cv2.polylines(img, [real_corners.astype(np.int32)], True, (150,50,255), thickness=3)
    cv2.polylines(img, [all_real_tile_centers.astype(np.int32)], False, (0,50,255), thickness=1)
    
    # Update mask with predicted chessboard
    cv2.drawContours(mask,[real_corners.astype(int)],0,1,-1)


  img_masked_full = cv2.bitwise_and(img,img,mask = (mask > 0.5).astype(np.uint8))
  img_masked = cv2.addWeighted(img,0.2,img_masked_full,0.8,0)

  drawMinAreaRect(img_masked, min_area_rect)

  return img_masked, edges_masked, warp_img
def process_img(img, name):

    #
    # WARP TO NEW PERSPECTIVE
    #

    source_points = get_image_points()
    img = camera.undistort(img)
    DEBUG.save_img_with_path(img, source_points, name)

    source_points = np.array(source_points, np.float32)
    destination_points = np.array(get_destination_points(), np.float32)
    M = cv2.getPerspectiveTransform(source_points, destination_points)
    warped = cv2.warpPerspective(img, M, camera.viewport_size(), flags=cv2.INTER_LINEAR)
    DEBUG.save_img(warped, "warped_" + name)

    #
    # CREATE BINARY IMAGE
    #

    # Create grayscale image
    grayscale_warped = cv2.cvtColor(warped, cv2.COLOR_RGB2GRAY)
    hls_warped = cv2.cvtColor(warped, cv2.COLOR_RGB2HLS)
    saturation_warped = hls_warped[:,:,2]
    l_warped = hls_warped[:,:,1]
    #DEBUG.save_img(saturation_warped, "warped_saturation_" + name)
    saturation_warped_threshold = np.zeros_like(saturation_warped)

    # edge detection on a combination of saturation and grayscale.
    # saturation is mostly useful on yellow. So this is our best bet.
    binary_sobelx = progressive_binary(saturation_warped, grayscale_warped, saturation_warped_threshold)
    #DEBUG.save_img(binary_sobelx, "binary_" + name)

    # find the peaks in the bottom half of the image. This is the starting
    # point for finding the lane.
    histogram = bottom_half_histogram(binary_sobelx)

    max_first_half = histogram[:len(histogram)//2].argmax()
    max_second_half = histogram[len(histogram)//2:].argmax() + len(histogram)//2
    annotated_image, left_path = find_lines(max_first_half, binary_sobelx)
    #DEBUG.save_img(annotated_image, "annotated_output_left_" + name + ".png")
    annotated_image, right_path = find_lines(max_second_half, binary_sobelx)
    #DEBUG.save_img(annotated_image, "annotated_output_right_" + name + ".png")

    #
    # Fit polylines to the detected lane points
    # 

    # Generate x and y values for plotting in projected space
    fit_poly_left = np.polyfit([x[1] for x in left_path], [x[0] for x in left_path], 2)
    fit_poly_right = np.polyfit([x[1] for x in right_path], [x[0] for x in right_path], 2)
    ploty = np.linspace(0, binary_sobelx.shape[0]-1, binary_sobelx.shape[0])
    left_fitx = fit_poly_left[0]*ploty**2 + fit_poly_left[1]*ploty + fit_poly_left[2]
    right_fitx = fit_poly_right[0]*ploty**2 + fit_poly_right[1]*ploty + fit_poly_right[2]
    
    # Convert left path back to original space
    path_left = list(zip(left_fitx, ploty))
    path_left = np.array([(path_left)], dtype=np.float32)
    reverse_transform = cv2.getPerspectiveTransform(destination_points, source_points)
    converted_left_path = cv2.perspectiveTransform(path_left, reverse_transform)
    
    # Convert right path back to original space
    path_right = list(zip(right_fitx, ploty))
    path_right = np.array([(path_right)], dtype=np.float32)
    converted_right_path = cv2.perspectiveTransform(path_right, reverse_transform)

    # Draw bounding box around the lane area
    overlay_image = np.zeros_like(img)
    bounding_array = np.concatenate( (converted_left_path[0], np.flipud(converted_right_path[0])) )
    bounding_box = np.array([bounding_array], dtype=np.int32)
    overlay_image = cv2.fillPoly(overlay_image, bounding_box, (0,255, 0))

    # this works fine
    #DEBUG.save_img(overlay_image, "overlay_image_" + name + ".png")
    result_image = cv2.addWeighted(img, 1, overlay_image, 0.3, 0)
    #DEBUG.save_img(result_image, "zoutput_" + name + ".png")

    # use plot to get us an image
    path_left = list(zip(left_fitx, ploty))
    path_left = np.array([(path_left)], dtype=np.float32)
    converted_left_path = cv2.perspectiveTransform(path_left, reverse_transform)
    path_right = list(zip(right_fitx, ploty))
    path_right = np.array([(path_right)], dtype=np.float32)
    converted_right_path = cv2.perspectiveTransform(path_right, reverse_transform)
    
    #
    # Curvature & offset in lane
    #

    # Calculate values
    left_curvature = calculate_curvature_meters(left_path)
    right_curvature = calculate_curvature_meters(right_path)
    average_curvature = (left_curvature + right_curvature) / 2.0
    offset = calculate_offset(left_path[0][0], right_path[0][0], binary_sobelx.shape[1])

    # Annotate the image
    font = cv2.FONT_HERSHEY_SIMPLEX
    text = 'Radius of curvature = {}m'.format(int(average_curvature))
    text2 = 'Offset from center = {}m'.format(offset)
    result_image = cv2.putText(result_image, text, (100,100), font, 1,(255,255,255),2,cv2.LINE_AA)
    result_image = cv2.putText(result_image, text2, (100,150), font, 1,(255,255,255),2,cv2.LINE_AA)
    DEBUG.save_img(result_image, "zzzfinal_output_" + name + ".png")
    return result_image
def getTransformation(img):
    """Gets the transformation matrix that would transform the image to be in a
    birds eye view. Reference points to use in calculating the matrix are
    specified by the user. User also specifies a distance threshold for social
    distancing, should be around 6 feet

    Args:
    - img: image to find the transformatino matrix for a birds eye view

    Returns:
      The 3x3 transformation matrix
      The number of pixels AFTER transformation that correspond to 6 feet
    """
    # grab reference to global image, set it
    global image
    image = img

    # Clone an unmodified copy of the image
    global clean_img
    clean_img = img.copy()

    global combined
    global T_matrix

    # grab reference to pressed key
    global keypress

    # grab reference to user specified line
    global linePts

    # Create named window that we will display on while the user picks the points
    cv2.namedWindow('Select reference points')
    cv2.setMouseCallback('Select reference points', drawPoints)

    # Show directions
    print(four_points)

    while True:
        # display image and wait for event
        cv2.imshow('Select reference points', image)
        key = cv2.waitKey(1) & 0xFF

        # if the 'c' key is pressed and all coordinates have been entered,
        # break from the loop
        if key == ord("c") and len(refPts) == 4:
            break

    # No longer need the window
    cv2.destroyAllWindows()

    T_matrix, warped = computeMatrix()

    combined = getTransformImg(warped)

    # Create window that we will display for user to confirm the transformation
    cv2.namedWindow('Check transformation')
    cv2.setMouseCallback('Check transformation', redoPoint)

    # Show directions
    print(check_transformation)

    while True:
        # display image and wait for event
        cv2.imshow('Check transformation', combined)
        key = cv2.waitKey(1) & 0xFF

        # if one of keys 1 to 4 is pressed, record it so mouse callback
        # can know which point to redo
        if key == ord("1"):
            keypress = 1
        elif key == ord('2'):
            keypress = 2
        elif key == ord('3'):
            keypress = 3
        elif key == ord('4'):
            keypress = 4
        elif key == ord("c"):
            break

    # No longer need the window
    cv2.destroyAllWindows()

    # Create named window that we will display on while the user picks the six foot long line
    cv2.namedWindow('Draw six foot long line')
    cv2.setMouseCallback('Draw six foot long line', drawLine)

    # Show directions
    print(specify_dist)

    clean_combined = combined.copy()

    while True:
        # display image and wait for event
        cv2.imshow('Draw six foot long line', combined)
        key = cv2.waitKey(1) & 0xFF

        # if the 'r' key is pressed, reset line
        if key == ord('r'):
            linePts.clear()
            combined = clean_combined.copy()
        elif key == ord('c') and len(linePts) == 2:
            break

    cv2.destroyAllWindows()

    points = np.array([linePts[0], linePts[1]])
    transformed = cv2.perspectiveTransform(np.float32([points]), T_matrix)[0]
    t1 = transformed[0]
    t2 = transformed[1]

    dist_thresh = (((t1[0] - t2[0])**2) + ((t1[1] - t2[1])**2))**0.5

    return T_matrix, int(dist_thresh)
Exemple #35
0
def processPhoto(codeDir,idir,fx,fy,cx,cy,k1,k2,k3,tangd1,tangd2,lengthOfInnerSquare, offsetBorder,horizontalDistanceBetweenCodeCenters, markerDictionary,  markerList, approxCodeHeightInPixels):    

    StartWatch('BeforeContourProcessing') 
    
    filename = codeDir+"\\"+idir
    p1=filename.find("IMG")
    p2=filename.find(".")
    imageNumber=filename[p1+len("IMG")-1:p2]
    
    print ("\n Image number is ", imageNumber)
    
    print ("\n file is ", filename,"\n")
    

    StartWatch('ReadImage')
   
    image = cv2.imread(filename)
    
    
    EndWatch('ReadImage')
    
    

    approxCodeHeightInPixels=  ( (5 * lengthOfInnerSquare) + (2* offsetBorder) ) * generate_codesSettings.pixelsPerMM
    
    
    approxCodeContourLength=approxCodeHeightInPixels*4
    approxCodeContourArea=approxCodeHeightInPixels*approxCodeHeightInPixels
  
    
    
    K = np.array([[fx,0,cx], [0, fy, cy], [0, 0, 1]])
    #K = np.array([[fx,0,0], [0, fy, 0], [cx, cy, 1]])
    d = np.array([k1,k2, 0, 0,k3]) # just use first two terms (no translation)
    dist=np.array([k1,k2, 0, 0,k3])
    #d=0
    
    
    h, w = image.shape[:2]
    imgHeight,imgWidth=image.shape[:2]
    horizontalCenterOfImage=w/2
    
     
    StartWatch('UndistortProcessing') 

    # undistort
    newcameramtx, roi = cv2.getOptimalNewCameraMatrix(K, dist, (w,h), 1,(w,h)) 
    xroi,yroi,wroi,hroi = roi
    #undistimg_w=wroi
    #undistimg_h=hroi
    
    
    undistimgBeforeCrop=np.zeros( (hroi,wroi,3) ,dtype = np.float32)
    undistimgBeforeCrop = cv2.undistort(image, K, d, None, newcameramtx)
    # now crop the image
    undistimg=undistimgBeforeCrop[yroi:yroi+hroi, xroi:xroi+wroi]
    
    # undistort
    #undistimgBeforeCrop1=np.zeros( (hroi,wroi,3) ,dtype = np.float32)
    mapx,mapy = cv2.initUndistortRectifyMap(K,dist,None,newcameramtx,(wroi,hroi),5)
    undistimgBeforeCrop1 = cv2.remap(image,mapx,mapy,cv2.INTER_LINEAR)
    undistimg1=undistimgBeforeCrop1[yroi:yroi+hroi, xroi:xroi+wroi]
    
    
    undistimg=undistimgBeforeCrop1
    
    EndWatch('UndistortProcessing') 
    
   
    
    StartWatch('BWThresholdProcessing') 
    
    
    cv2DebugWrite('c:\\temp\\image.png',image)
    cv2DebugWrite('c:\\temp\\undistimage.png',undistimg)
    cv2DebugWrite('c:\\temp\\undistimage1.png',undistimg1)
    cv2DebugWrite('c:\\temp\\undistimageBeforeCrop.png',undistimgBeforeCrop)
    cv2DebugWrite('c:\\temp\\undistimageBeforeCrop1.png',undistimgBeforeCrop1)
    

    imsdup=np.zeros_like(undistimg)
    #imsdup[:] = undistimg
    
    imsdup1 = np.empty_like (undistimg)
    imsdup1[:] = undistimg
    

    
    gray1=cv2.cvtColor(undistimg,cv2.COLOR_BGR2GRAY)
    #ret,thresh = cv2.threshold(gray,127,255,1)
    ret,thresh = cv2.threshold(gray1,128,255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
    

    
    
    # rough approach to ignoring codes in distorted area
  
    widthQ=int(generate_codesSettings.distortionAreaRemoveFudgeFactor*w)
    heightQ=int(generate_codesSettings.distortionAreaRemoveFudgeFactor*h)
    threshdup=np.zeros_like(thresh)
    threshdup[heightQ:h-heightQ, widthQ:w-widthQ]=thresh[heightQ:h-heightQ, widthQ:w-widthQ]
    thresh=threshdup
    

    
    
    
    cv2DebugWrite('c:\\temp\\thresh.png',thresh)
    
    EndWatch('BWThresholdProcessing') 

    
    EndWatch('BeforeContourProcessing') 
    StartWatch('ContourProcessing') 
    


    #_,contours,h= cv2.findContours(thresh, cv2.RETR_LIST , cv2.CHAIN_APPROX_SIMPLE)
    _,contours,h= cv2.findContours(thresh, cv2.RETR_LIST , cv2.CHAIN_APPROX_NONE)
    cv2.drawContours(imsdup, contours, -1, (255, 0, 0), 3)
    cv2DebugWrite("c:\\temp\\rawcontours.png",imsdup)
    
    
    scnts4=[cntitem1 for cntitem1 in contours if len(cv2.approxPolyDP(cntitem1,0.01*cv2.arcLength(cntitem1,True),True))==4] 
    
     
    
    cv2.drawContours(imsdup, scnts4, -1, (255, 0, 0), 3)
    cv2DebugWrite("c:\\temp\\cont4sides.png",imsdup)
    



    scnts4WithLength=[(cntitem1,   cv2.arcLength(cntitem1,True)  ) for cntitem1 in contours if ( (len(cv2.approxPolyDP(cntitem1,0.01*cv2.arcLength(cntitem1,True),True))==4 ) and (cv2.contourArea(cntitem1)>1300) )] 

    scnts4WithLengthPossibleCode=[ item for item in scnts4WithLength if (item[1]>approxCodeContourLength*0.80) & (item[1]<approxCodeContourLength*1.2) ]
    
    contoursCodesOnly= [cntitem[0] for cntitem in scnts4WithLengthPossibleCode  ]
    fudgeFactorAreaThresholdDiff=8000
    contoursFilteredByArea=  [ cntitem for cntitem in contoursCodesOnly if abs((cv2.contourArea(cntitem)-approxCodeContourArea))  <fudgeFactorAreaThresholdDiff                       ] 
    
          
    



    contoursCodesOnlyFBA= [cntitem for cntitem in contoursFilteredByArea  ]
    contoursPlusMoments=  [   ( cntitem1, cv2.moments(cntitem1) )     for cntitem1 in contoursCodesOnlyFBA ] 
    #contoursPlusCenters=  [    (  int(M['m10']/M['m00']) , int(M['m01']/M['m00']) )    for M  in contoursPlusMoments ] 
    #contoursPlusCenters=  [   ( cm[0], (  int(cm[1]['m10']/cm[1]['m00']),  int(cm[1]['m01']/cm[1]['m00'])    )   )    for cm  in contoursPlusMoments ] 
    contoursPlusCenters=  [   ( cm[0], (  int(cm[1]['m10']/cm[1]['m00']),  int(cm[1]['m01']/cm[1]['m00'])    )   )    for cm  in contoursPlusMoments ] 
    #contoursPlusCenters=  [   ( cm[0], (  int(cm[1]['m10']/cm[1]['m00']),  int(cm[1]['m01']/cm[1]['m00'])    )   )    for cm  in contoursPlusMoments ] 
    print ("\n length of contoursPlusCenters +++ ********\n", len(contoursPlusCenters))
   
    contoursNearExpectedPosition = [ cm[0] for cm in contoursPlusCenters if checkCodeNearExpectedHorizontalPosition(cm[1][0],generate_codesSettings.pixelsPerMM,horizontalCenterOfImage,horizontalDistanceBetweenCodeCenters)   ]
    
   # print ("\n length of contours ********\n", len(contoursNearExpectedPosition))
    #hack
    #contoursNearExpectedPosition=contoursCodesOnly
    print ("\n length of scnts4WithLength ********\n", len(scnts4WithLength))
    print ("\n length of scnts4WithLengthPossibleCode ********\n", len(scnts4WithLengthPossibleCode))
    print ("\n length of contoursCodesOnly ********\n", len(contoursCodesOnly))
    print ("\n length of contoursFilteredByArea ********\n", len(contoursFilteredByArea))
    print ("\n length of contoursPlusMoments ********\n", len(contoursPlusMoments))
    print ("\n length of contoursPlusCenters ********\n", len(contoursPlusCenters))
  
    
    print ("\n length of contoursNearExpectedPosition ********\n", len(contoursNearExpectedPosition))
    
    
    imsdupAll=np.zeros_like(undistimg)
    #cv2.drawContours(imsdupAll, contoursNearExpectedPosition, 3, (255, 0, 0), 3)
    cv2DebugWrite("c:\\temp\\contimgAll.png",imsdup)
    
    for i in range(len(contoursNearExpectedPosition)):
        imsdupAll=np.zeros_like(undistimg)
        cv2.drawContours(imsdupAll, contoursNearExpectedPosition[i], -1, (255, 0, 0), 3)
        filenamec="c:\\temp\\contnum_"+str(i)+".jpg"
        cv2DebugWrite(filenamec,imsdupAll)
        

    
    numberOfBoxes=len(contoursNearExpectedPosition)
    
    
    codeBoxArray1L=np.zeros(  (numberOfBoxes,4,generate_codesSettings.maxNumberOfPtsPerSide, 2) ,dtype = np.int32)

    codeBoxCorners1L=np.zeros( (numberOfBoxes ,4,2) ,dtype = np.float32)
    

    
    for boxID,boxItem  in enumerate(contoursNearExpectedPosition):
        boxFormContourBox3(boxItem,boxID, codeBoxArray1L,generate_codesSettings.maxNumberOfPtsPerSide)     

#
    EndWatch('ContourProcessing') 
    
    #numberOfRows=100
    codeBoxLocalCenter=np.zeros( (numberOfBoxes,2) ,dtype = np.float32)
    codeBoxExactCenter=np.zeros( (numberOfBoxes,2) ,dtype = np.float32)
    codeBoxCode=np.zeros( (numberOfBoxes) ,dtype = np.int32)
  

    
    
    
    totalErrorTally=0
    codeList=[]
    

    
    StartWatch('BoxProcessing') 
 
    
    for boxNumber in range(numberOfBoxes):
            if (np.count_nonzero(codeBoxArray1L[boxNumber])==0):
#                print "\n 77777777777 Continue"
                continue
            print ("\n ******** Box Number ", boxNumber)
            leftMostPointsFromBox=codeBoxArray1L[boxNumber,3].flatten() [np.flatnonzero(codeBoxArray1L[boxNumber,3])].reshape(-1,2)
            rightMostPointsFromBox=codeBoxArray1L[boxNumber,1].flatten() [np.flatnonzero(codeBoxArray1L[boxNumber,1])].reshape(-1,2)
            topMostPointsFromBox=codeBoxArray1L[boxNumber,0].flatten() [np.flatnonzero(codeBoxArray1L[boxNumber,0])].reshape(-1,2)
            bottomMostPointsFromBox=codeBoxArray1L[boxNumber,2].flatten() [np.flatnonzero(codeBoxArray1L[boxNumber,2])].reshape(-1,2)
          
    
          
            [vxLM,vyLM,xLM,yLM] = cv2.fitLine(leftMostPointsFromBox,cv2.DIST_FAIR,0,0.01,0.01).flatten()
            #print "\n $$$$$$$$$$$$$ rightMostPointsFromBox\n",rightMostPointsFromBox
            [vxRM,vyRM,xRM,yRM] = cv2.fitLine(rightMostPointsFromBox,cv2.DIST_FAIR,0,0.01,0.01).flatten()
            [vxTM,vyTM,xTM,yTM] = cv2.fitLine(topMostPointsFromBox,cv2.DIST_FAIR,0,0.01,0.01).flatten()
            [vxBM,vyBM,xBM,yBM] = cv2.fitLine(bottomMostPointsFromBox,cv2.DIST_FAIR,0,0.01,0.01).flatten()
    
        
            topMost=graphLine1(undistimg,vxTM,vyTM,xTM,yTM,(255,255,0),0.5)
            #print "\n *****TM****", rowNumber, columnNumber,vxTM,vyTM,xTM,yTM
            rightMost=graphLine1(undistimg,vxRM,vyRM,xRM,yRM,(255,0,0),0.5)
            #print "\n *****RM****", rowNumber, columnNumber, vxRM,vyRM,xRM,yRM
            bottomMost=graphLine1(undistimg,vxBM,vyBM,xBM,yBM,(0,255,255),0.5)
            #print "\n *****BM****", rowNumber, columnNumber, vxBM,vyBM,xBM,yBM
            leftMost=graphLine1(undistimg,vxLM,vyLM,xLM,yLM,(0,0,255),0.5)
            #print "\n *****LM******", rowNumber, columnNumber,vxLM,vyLM,xLM,yLM
            
            cv2DebugWrite("c:\\temp\\img_state.jpg", undistimg)
            
            topLeft=line_intersection( leftMost, topMost)
            topRight=line_intersection( rightMost, topMost)
            bottomRight=line_intersection( rightMost, bottomMost)
            bottomLeft=line_intersection( leftMost, bottomMost)
            
#            print "\n Corners of Box", topLeft, topRight, bottomRight, bottomLeft
           
            
            codeBoxCorners1L[boxNumber,0]= np.array([ int(topLeft[0]), int(topLeft[1])          ])
            codeBoxCorners1L[boxNumber,1]= np.array([ int(topRight[0]), int(topRight[1])          ])
            codeBoxCorners1L[boxNumber,2]= np.array([ int(bottomRight[0]), int(bottomRight[1])          ])
            codeBoxCorners1L[boxNumber,3]= np.array([ int(bottomLeft[0]), int(bottomLeft[1])          ])
            
           
            
            print ("\n**** ", codeDir, idir, "\n **** Corners",codeBoxCorners1L[boxNumber,0],codeBoxCorners1L[boxNumber,1],codeBoxCorners1L[boxNumber,2],codeBoxCorners1L[boxNumber,3],"\n" )
           
           
          
 
             
          
            destBox1=np.array([  
                [0,0  ],
                [generate_codesSettings.maxSizeCodeBoxInPixels,0 ],
                [generate_codesSettings.maxSizeCodeBoxInPixels,generate_codesSettings.maxSizeCodeBoxInPixels ],
                [0,generate_codesSettings.maxSizeCodeBoxInPixels ],
              
                ],dtype = "float32")
    
    
    
            cv2DebugWrite("c:\\temp\\testme.jpg", imsdup1)                 
            localBoxTransform= cv2.getPerspectiveTransform(  codeBoxCorners1L[boxNumber] ,  destBox1    )
            #localBoxImg=np.zeros( (500,500,3) ,dtype = np.float32)
            filenamebox="c:\\temp\\localBox"+str(boxNumber)+"_.jpg"
            warp = cv2.warpPerspective(imsdup1,localBoxTransform,(generate_codesSettings.maxSizeCodeBoxInPixels,generate_codesSettings.maxSizeCodeBoxInPixels))
            cv2DebugWrite(filenamebox, warp)
            
            code=decodeBox(warp,lengthOfInnerSquare,offsetBorder)
            codeBoxCode[boxNumber]=code
            print ("\n&&&&&&&&&&&&&&& Code is ", code)
            if str(code) not in markerDictionary:            
                code=FixCode(code, markerList, 2)
                if (code==0):
                    codeBoxLocalCenter[boxNumber]=np.array([   0,0       ]) 
                    continue
            
            centerSmall = line_intersection(  (  topLeft, bottomRight     ), ( topRight,  bottomLeft     ) )
            codeBoxLocalCenter[boxNumber]=np.array([centerSmall[0],  centerSmall[1]]) 
            
            codeBoxExactCenter[boxNumber]=np.array((float(markerDictionary[str(code)][0]),float(markerDictionary[str(code)][1])       )).reshape(-1,2)

            codeList.append(code)
            
   

    EndWatch('BoxProcessing') 
            
  
    StartWatch('ErrorMeasureProcessing')     

   
    cbec=codeBoxExactCenter.flatten() [np.flatnonzero(codeBoxExactCenter)].reshape(-1,2)
    cblc=codeBoxLocalCenter.flatten() [np.flatnonzero(codeBoxLocalCenter)].reshape(-1,2)
    numNonZeroCodes=cblc.shape[0]
    
    minNumberCorrectCodesPerPicture=3
    codeErrors=False
    if (numNonZeroCodes<minNumberCorrectCodesPerPicture):
        codeErrors=True
        return ( (codeErrors, 0,0,0,0,0 ) )
    
    #perspTrAllPts,mask=cv2.findHomography(codeBoxLocalCenter.reshape(-1,2), codeBoxExactCenter.reshape(-1,2) )
    perspTrAllPts,mask=cv2.findHomography(cblc,cbec)
    
    if perspTrAllPts is None:
        codeErrors=True
        return ( (codeErrors, 0,0,0,0,0 ) )
        
    #cbmc=np.zeros_like( cbec ,dtype = np.float32)
    
    #codeBoxMappedCenter=cv2.perspectiveTransform( cblc.reshape(1,numberOfRows*2,2),perspTrAllPts)
    cbmc=cv2.perspectiveTransform( cblc.reshape(1,numNonZeroCodes,2),perspTrAllPts)
    
    

    
    imgUndist = np.empty_like (undistimg)
    imgUndist[:] = undistimg
    filenameperscorrected="c:\\temp\\IMGPersCorr.jpg"
    warp = cv2.warpPerspective(imgUndist,perspTrAllPts,(imgWidth,imgHeight))
    cv2DebugWrite(filenameperscorrected, warp)
    
    
    
    distResult=spsd.cdist(cbmc.reshape(-1,2),cbec.reshape(-1,2) )
    
    rmsError=np.sqrt(totalErrorTally)/(numberOfBoxes*2)
    
    perspTrAllPtsInv=np.linalg.inv(perspTrAllPts)
    cbinferredcenters=cv2.perspectiveTransform( cbec.reshape(1,numNonZeroCodes,2),perspTrAllPtsInv)
   
    rvec=np.array([0,0,0])
    tvec=np.array([0,0,0])
    print ("\nRMS ",rmsError)
    
    
    # generate visual of error by drawing circles around the error (based on filename and undistimg)
    showErrorsFileName=filename
    showErrorsFileName=showErrorsFileName.replace("IMG_", "IMAGEcenter_")
    
    showErrors = np.empty_like (undistimg)
    showErrors[:] = undistimg
    
    for numcodes in range(len(codeList)):
    # for each target - draw a circle around the center
        clr=(255,0,255)
        resultP1=( (     int(cbinferredcenters[0,numcodes,0])        , int(cbinferredcenters[0,numcodes,1]) ) )
        print ("\n Pt is ", resultP1)
        
        cv2.circle(showErrors,resultP1,8 ,clr,1)
        #cv2.circle(showErrors,resultP1,8 ,clr,2)
        errorForCode=distResult[numcodes,numcodes]
       
        resultP1TextError= ( (     int(cbinferredcenters[0,numcodes,0]+110)        , int(cbinferredcenters[0,numcodes,1]) ) )
        resultP1TextCode = ( (     int(cbinferredcenters[0,numcodes,0]-310)        , int(cbinferredcenters[0,numcodes,1]) ) )


        #cv2.putText(showErrors,str(errorForCode),resultP1Text,cv2.FONT_HERSHEY_SIMPLEX,clr)
        cv2.putText(showErrors,str(errorForCode), resultP1TextError, cv2.FONT_HERSHEY_SIMPLEX, 1, 255)
        cv2.putText(showErrors,str(codeList[numcodes]), resultP1TextCode, cv2.FONT_HERSHEY_SIMPLEX, 1, 255)
        
    print ("\n*** SHow error file name is", showErrorsFileName)
    cv2DebugWrite(showErrorsFileName, showErrors)
    
    
    
#    print "\n\n777777777777\n" , topLeft,topRight,bottomLeft,bottomRight
    
    
    
    cv2DebugWrite("c:\\temp\\lineq.png", undistimg)

    EndWatch('ErrorMeasureProcessing')     
    
    return ( (codeErrors, codeList, cbinferredcenters, distResult,mapx,mapy) )
Exemple #36
0
def siftComp(img1, nloop):
    acc = 0
    sift = cv2.xfeatures2d.SIFT_create(nfeature)
    kp, res = sift.detectAndCompute(img1, None)
    pts = np.array([[[k.pt[0], k.pt[1]] for k in kp]])
    responses = np.array([k for k in range(0, len(kp))])
    knn = cv2.ml.KNearest_create()
    knn.train(res, cv2.ml.ROW_SAMPLE, responses)
    sift = cv2.xfeatures2d.SIFT_create(1000)
    for i in range(0, nloop):
        print "******This is the " + str(i) + " loop*******"
        img2, M = method.dataIncreasing_camera(img1)
        dst = cv2.perspectiveTransform(pts, M)
        dst = [(int(k[0]), int(k[1])) for k in dst[0]]
        kp2, res2 = sift.detectAndCompute(img2, None)
        for k in dst:
            img2 = cv2.circle(img2, k, 2, (55, 255, 155), 2)
        out = cv2.drawKeypoints(img2, kp2, img2)
        matchs = []
        nTure = []
        nFalse = []
        nnTure = []
        nnFalse = []
        print len(res2)
        if res2 == None:
            neighbours = []
        else:
            ret, results, neighbours, dist = knn.findNearest(res2, 3)
        for k in range(0, len(neighbours)):
            # print dst[int(neighbours[k][0])]

            (x0, y0) = dst[int(neighbours[k][0])]
            (x1, y1) = kp2[k].pt
            err = np.sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0))
            if err < 3:
                if distinguish[0, int(neighbours[k][0])] == 0 or distinguish[0, int(neighbours[k][0])] < dist[k][0] / \
                        dist[k][1]:
                    distinguish[
                        0, int(neighbours[k][0])] = dist[k][0] / dist[k][1]
                img2 = cv2.circle(img2, (x0, y0), 6, (255, 155, 55), 1)
                apprearance[int(neighbours[k][0])] += 1
                # print "GOOD NO." + str(int(neighbours[k][0])) + "\nthe shortest distence is:" + str(dist[k])
                if dist[k][0] < predict[int(neighbours[k][0])]:
                    print "Preduct is True"
                    nTure.append(int(neighbours[k][0]))
                else:
                    print "Preduct is False"
                    nFalse.append(int(neighbours[k][0]))
                if dist[k][0] > weigh[int(neighbours[k][0]), 0]:
                    weigh[int(neighbours[k][0]), 0] = dist[k][0]
                    predict[int(neighbours[k][0])] = min(
                        weigh[int(neighbours[k][0]), 0],
                        weigh[int(neighbours[k][0]), 1])
                    match = cv2.DMatch(int(neighbours[k][0]), k, 3)
                    matchs.append(match)
            else:
                if distinguish[1, int(neighbours[k][0])] == 0 or distinguish[1, int(neighbours[k][0])] > dist[k][0] / \
                        dist[k][1]:
                    distinguish[
                        1, int(neighbours[k][0])] = dist[k][0] / dist[k][1]
                # print "BAD NO." + str(int(neighbours[k][0])) + "\nthe shortest distence is:" + str(dist[k])
                if dist[k][0] < predict[int(neighbours[k][0])]:
                    print "Preduct is False"
                    nnFalse.append(int(neighbours[k][0]))
                else:
                    print "Preduct is True"
                    nnTure.append(int(neighbours[k][0]))
                if 0 == weigh[int(neighbours[k][0]),
                              1] or dist[k][0] < weigh[int(neighbours[k][0]),
                                                       1]:
                    weigh[int(neighbours[k][0]), 1] = dist[k][0]
                    predict[int(neighbours[k][0])] = min(
                        weigh[int(neighbours[k][0]), 0],
                        weigh[int(neighbours[k][0]), 1])
        print apprearance
        print "The number of true match and false match is " + str(
            (len(nTure), len(nFalse), len(nTure) * 1.0 /
             (len(nFalse) + len(nTure) + 0.001)))
        print "The number of true match and false match is " + str(
            (len(nTure), len(nnFalse), len(nTure) * 1.0 /
             (len(nnFalse) + len(nTure) + 0.001)))

        acc += len(nTure) * 1.0 / (len(nnFalse) + len(nTure) + 0.001)

    print acc / nloop
    out = cv2.drawMatches(img1, kp, img2, kp2, matchs, out)
    cv2.imshow("sift picture of translation", out)

    return
Exemple #37
0
    def image_callback(self, msg):
        image = self.bridge.compressed_imgmsg_to_cv2(msg,
                                                     desired_encoding='bgr8')
        imageGray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

        cv2.useOptimized()
        cv2.setUseOptimized(True)

        kp1, des1 = self.surf.detectAndCompute(self.blocking_img, None)
        kp2, des2 = self.surf.detectAndCompute(imageGray, None)

        FLANN_INDEX_KDTREE = 1

        index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
        search_params = dict(checks=50)

        matches = None

        try:
            flann = cv2.FlannBasedMatcher(index_params, search_params)
            matches = flann.knnMatch(des1, des2, k=2)

        except Exception as ex:
            print('knnMatch error')

            return

        good = []

        for m, n in matches:
            if m.distance < 0.7 * n.distance:
                good.append(m)

        outer_dst_pts = np.float32([])

        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)

            outer_dst_pts = dst_pts

            M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)

            matchesMask = mask.ravel().tolist()

            h, w, d = self.blocking_img.shape

            pts = np.float32([[0, 0], [0, h - 1], [w - 1, h - 1],
                              [w - 1, 0]]).reshape(-1, 1, 2)

            dst = None

            try:
                dst = cv2.perspectiveTransform(pts, M)

            except Exception as ex:
                print('perspectiveTransform error: dst = %s' % dst)

                return

            image = cv2.polylines(image, [np.int32(dst)], True, (255, 0, 0), 3,
                                  cv2.LINE_AA)

            self.match = True

            rospy.logdebug('차단바 표지판 탐지 : %s' % self.match)

        else:
            self.match = False

            rospy.logdebug("Not enough matches are found - {}/{}".format(
                len(good), MIN_MATCH_COUNT))

            matchesMask = None

        draw_params = dict(matchColor=(0, 255, 0),
                           singlePointColor=None,
                           matchesMask=matchesMask,
                           flags=2)

        matches_img = cv2.drawMatches(self.blocking_img, kp1, image, kp2, good,
                                      None, **draw_params)

        if show_matched_points:
            for pt in outer_dst_pts:
                x, y = pt[0]

                cv2.circle(image, (x, y), 3, (0, 0, 255), -1)

        self.match_pub.publish(self.match)

        #cv2.imshow('match', matches_img)
        cv2.imshow("image", image)

        cv2.waitKey(3)
	point_3d_R[i, 0, 2] = disparity[0, i]
	for j in range(2):
		point_3d_R[i, 0, j] = undistortPoints_R[i, 0, j]

# point_3d_L[0,0,0] = undistortPoints_L[0,0,0]
# point_3d_L[0,0,1] = undistortPoints_L[0,0,1]
# point_3d_L[0,0,2] = disparity[0,0]
#
# point_3d_L[1,0,0] = undistortPoints_L[1,0,0]
# point_3d_L[1,0,1] = undistortPoints_L[1,0,1]
# point_3d_L[1,0,2] = disparity[0,1]
#
# point_3d_L[2,0,0] = undistortPoints_L[2,0,0]
# point_3d_L[2,0,1] = undistortPoints_L[2,0,1]
# point_3d_L[2,0,2] = disparity[0,2]
#
# point_3d_L[3,0,0] = undistortPoints_L[3,0,0]
# point_3d_L[3,0,1] = undistortPoints_L[3,0,1]
# point_3d_L[3,0,2] = disparity[0,3]

print('point_3d_L = ', point_3d_L)
print('point_3d_R = ', point_3d_R)

perspectiveTransform_L = cv2.perspectiveTransform(point_3d_L, Q)
print('perspectiveTransform_L = ', perspectiveTransform_L)

perspectiveTransform_R = cv2.perspectiveTransform(point_3d_R, Q)
print('perspectiveTransform_R = ', perspectiveTransform_R)

cv2.destroyAllWindows()
    def match_car(self, target_gray, colour):
        
        if colour == GREEN:
            self.source = self.source_green
            self.h = self.h_g
            self.w = self.w_g
            self.kp_source = self.kp_source_g
            self.desc_source = self.desc_source_g
            homography_threshold = HOMOGRAPHY_THRESHOLD
            filter_match_threshold = FILTER_MATCH_THRESHOLD
        elif colour == BLUE:
            self.source = self.source_blue
            self.h = self.h_b
            self.w = self.w_b
            self.kp_source = self.kp_source_b
            self.desc_source = self.desc_source_b
            homography_threshold = HOMOGRAPHY_THRESHOLD
            filter_match_threshold = FILTER_MATCH_THRESHOLD
        else:
            self.source = self.source_yellow
            self.h = self.h_y
            self.w = self.w_y
            self.kp_source = self.kp_source_y
            self.desc_source = self.desc_source_y
            homography_threshold = HOMOGRAPHY_THRESHOLD_YELLOW
            filter_match_threshold = FILTER_MATCH_THRESHOLD_YELLOW
         
        #use sift to get keypoints and descriptors in the frame 
        kp_target, desc_target = self.sift.detectAndCompute(target_gray, None)
         
        #match the descriptors of the target and the descriptors of the frame
        #matches is a list of matching points in the target and descriptor.
        matches = self.flann.knnMatch(self.desc_source, desc_target, k=2) 
        
        #filter only for good matches
        #this is done by cutting out points with abnormally large distances    
        good_pts = []
        for m, n in matches:
            if m.distance < filter_match_threshold*n.distance:
                good_pts.append(m)
         
        #draw the found matches of keypoints from two images 
        #output_matches = cv.drawMatches(self.source_img, self.kp_source, target_gray, kp_target, \
        #                             good_pts, target_gray)
        
	    #Homography
        if len(good_pts) > homography_threshold:
            #if there are this many points, draw homography
             
            #query index gives position of the points in the query image
            #this extracts those points and reshapes it
            query_pts = np.float32([self.kp_source[m.queryIdx].pt \
                                                 for m in good_pts]).reshape(-1,1,2)        
        
            train_pts = np.float32([kp_target[m.trainIdx].pt \
                                                 for m in good_pts]).reshape(-1,1,2)
        
            #obtains the perspective transformation between two sets of points 
            matrix, mask = cv.findHomography(query_pts, train_pts, cv.RANSAC, 5.0)
        
            #if no homography can be found
            if matrix is None:
                
                print("SCENARIO 1 HAPPENED")
                print("DUMP: {}".format(query_pts))

                return None
                #TESTING
                #return (target_gray, output_matches)
 
            else:
                #do a perspective transform to change the orientation of the homography
                # with respect to the original image
                pts = np.float32([[0, 0], [0, self.h], [self.w, self.h], \
                                 [self.w, 0]]).reshape(-1,1,2)
                dst = cv.perspectiveTransform(pts, matrix)            
                dst = np.int32(dst) 

                #Find the maximum and minimum x and y points
                max_x = dst[0][0][0]
                min_x = dst[0][0][0]
                
                max_y = dst[0][0][1]
                min_y = dst[0][0][1]
                
                for i in range(len(dst)):
                    
                    if max_x < dst[i][0][0]:
                        max_x = dst[i][0][0]
                    if min_x > dst[i][0][0]:
                        min_x = dst[i][0][0]

                    if max_y < dst[i][0][1]:
                        max_y = dst[i][0][1]
                    if min_y > dst[i][0][1]:
                        min_y = dst[i][0][1]

                if max_x - min_x < HOM_LOW or max_x - min_x > HOM_HIGH:

                    print("SCENARIO 2 HAPPENED")
                    return None
                    #TESTING
                    #return (target_gray, output_matches)
                elif max_y - min_y < HOM_LOW or max_y - min_y > HOM_HIGH:
                    
                    print("SCENARIO 3 HAPPENED")
                    return None
                    #TESTING
                    #return (target_gray, output_matches)
                else:
                    return ((min_x, min_y), (max_x, max_y)) 
                    #TESTING
                    #dst = [dst]
                    #draw the homography and show it 
                    #homography = cv.polylines(target_gray, [np.int32(dst)], True, (255, 0, 0), 3)
                    #return (homography, output_matches)
        else:
            
            train_pts = np.float32([kp_target[m.trainIdx].pt \
                                                 for m in good_pts]).reshape(-1,1,2)
             
            print("SCENARIO 4 HAPPENED")
            print("DUMP: {}".format(train_pts))
            
            return None
Exemple #40
0
def compute_transformed_contour(width,
                                height,
                                fontsize,
                                M,
                                contour,
                                minarea=0.5):
    """Compute the permitted drawing contour
    on a padded canvas for an image of a given size.
    We assume the canvas is padded with one full image width
    and height on left and right, top and bottom respectively.

    Args:
        width: Width of image
        height: Height of image
        fontsize: Size of characters
        M: The transformation matrix
        contour: The contour to which we are limited inside
            the rectangle of size width / height
        minarea: The minimum area required for a character
            slot to qualify as being visible, expressed as
            a fraction of the untransformed fontsize x fontsize
            slot.
    """
    spacing = math.ceil(fontsize / 2)
    xslots = int(np.floor(width / spacing))
    yslots = int(np.floor(height / spacing))
    ys, xs = np.mgrid[:yslots, :xslots]
    basis = np.concatenate([xs[..., np.newaxis], ys[..., np.newaxis]],
                           axis=-1).reshape((-1, 2))
    basis *= spacing
    slots_pretransform = np.concatenate([
        (basis + offset)[:, np.newaxis, :]
        for offset in [[0, 0], [spacing, 0], [spacing, spacing], [0, spacing]]
    ],
                                        axis=1)
    slots = cv2.perspectiveTransform(src=slots_pretransform.reshape(
        (1, -1, 2)).astype('float32'),
                                     m=M)[0]
    inside = np.array([
        cv2.pointPolygonTest(contour=contour, pt=(x, y), measureDist=False) >=
        0 for x, y in slots
    ]).reshape(-1, 4).all(axis=1)
    slots = slots.reshape(-1, 4, 2)
    areas = np.abs(
        (slots[:, 0, 0] * slots[:, 1, 1] - slots[:, 0, 1] * slots[:, 1, 0]) +
        (slots[:, 1, 0] * slots[:, 2, 1] - slots[:, 1, 1] * slots[:, 2, 0]) +
        (slots[:, 2, 0] * slots[:, 3, 1] - slots[:, 2, 1] * slots[:, 3, 0]) +
        (slots[:, 3, 0] * slots[:, 0, 1] -
         slots[:, 3, 1] * slots[:, 0, 0])) / 2
    slots_filtered = slots_pretransform[(areas > minarea * spacing * spacing)
                                        & inside]
    temporary_image = cv2.drawContours(image=np.zeros((height, width),
                                                      dtype='uint8'),
                                       contours=slots_filtered,
                                       contourIdx=-1,
                                       color=255)
    temporary_image = cv2.dilate(src=temporary_image,
                                 kernel=np.ones((spacing, spacing)))
    newContours, _ = cv2.findContours(temporary_image,
                                      mode=cv2.RETR_TREE,
                                      method=cv2.CHAIN_APPROX_SIMPLE)
    x, y = slots_filtered[0][0]
    contour = newContours[next(
        index for index, contour in enumerate(newContours)
        if cv2.pointPolygonTest(contour=contour, pt=(
            x, y), measureDist=False) >= 0)][:, 0, :]
    return contour
Exemple #41
0
def draw_text_image(text,
                    fontsize,
                    height,
                    width,
                    fonts,
                    use_ligatures=False,
                    thetaX=0,
                    thetaY=0,
                    thetaZ=0,
                    color=(0, 0, 0),
                    permitted_contour=None,
                    draw_contour=False):
    """Get a transparent image containing text.

    Args:
        text: The text to draw on the image
        fontsize: The size of text to show.
        height: The height of the output image
        width: The width of the output image
        fonts: A dictionary of {subalphabet: paths_to_font}
        thetaX: Rotation about the X axis
        thetaY: Rotation about the Y axis
        thetaZ: Rotation about the Z axis
        color: The color of drawn text
        permitted_contour: A contour defining which part of the image
            we can put text. If None, the entire canvas is permitted
            for text.
        use_ligatures: Whether to render ligatures. If True,
            ligatures are always used (with an initial check for support
            which sometimes yields false positives). If False, ligatures
            are never used.

    Returns:
        An (image, sentence, lines) tuple where image is the
        transparent text image, sentence is the full text string,
        and lines is a list of lines where each line itself is a list
        of (box, character) tuples.
    """
    # pylint: disable=bad-continuation
    if not use_ligatures:
        fonts = {
            subalphabet: PIL.ImageFont.truetype(font_path, size=fontsize)
            if font_path is not None else PIL.ImageFont.load_default()
            for subalphabet, font_path in fonts.items()
        }
    if use_ligatures:
        for subalphabet, font_path in fonts.items():
            ligatures_supported = True
            font = PIL.ImageFont.truetype(
                font_path, size=fontsize
            ) if font_path is not None else PIL.ImageFont.load_default()
            for ligature in LIGATURES:
                try:
                    font.getsize(ligature)
                except UnicodeEncodeError:
                    ligatures_supported = False
                    break
            if ligatures_supported:
                del fonts[subalphabet]
                subalphabet += LIGATURE_STRING
            fonts[subalphabet] = font
        for insert, search in LIGATURES.items():
            for subalphabet in fonts.keys()():
                if insert in subalphabet:
                    text = text.replace(search, insert)
    character_font_pairs = [(character,
                             next(font for subalphabet, font in fonts.items()
                                  if character in subalphabet))
                            for character in text]
    M = get_rotation_matrix(width=width,
                            height=height,
                            thetaZ=thetaZ,
                            thetaX=thetaX,
                            thetaY=thetaY)
    if permitted_contour is None:
        permitted_contour = np.array([[0, 0], [width, 0], [width, height],
                                      [0, height]]).astype('float32')
    character_sizes = np.array([
        font.font.getsize(character)
        for character, font in character_font_pairs
    ])
    min_character_size = character_sizes.sum(axis=1).min()
    transformed_contour = compute_transformed_contour(
        width=width,
        height=height,
        fontsize=max(min_character_size, 1),
        M=M,
        contour=permitted_contour)
    start_x = transformed_contour[:, 0].min()
    start_y = transformed_contour[:, 1].min()
    end_x = transformed_contour[:, 0].max()
    end_y = transformed_contour[:, 1].max()
    image = PIL.Image.new(mode='RGBA',
                          size=(width, height),
                          color=(255, 255, 255, 0))
    draw = PIL.ImageDraw.Draw(image)
    lines = [[]]
    sentence = ''
    x = start_x
    y = start_y
    max_y = start_y
    out_of_space = False
    for character_index, (character, font) in enumerate(character_font_pairs):
        if out_of_space:
            break
        (character_width,
         character_height), (offset_x,
                             offset_y) = character_sizes[character_index]
        if character in LIGATURES:
            subcharacters = LIGATURES[character]
            dx = character_width / len(subcharacters)
        else:
            subcharacters = character
            dx = character_width
        x2, y2 = (x + character_width + offset_x,
                  y + character_height + offset_y)
        while not all(
                cv2.pointPolygonTest(
                    contour=transformed_contour, pt=pt, measureDist=False) >= 0
                for pt in [(x, y), (x2, y), (x2, y2), (x, y2)]):
            if x2 > end_x:
                dy = max(1, max_y - y)
                if y + dy > end_y:
                    out_of_space = True
                    break
                y += dy
                x = start_x
            else:
                x += fontsize
            if len(lines[-1]) > 0:
                # We add a new line whether we have advanced
                # in the y-direction or not because we also want to separate
                # horizontal segments of text.
                lines.append([])
            x2, y2 = (x + character_width + offset_x,
                      y + character_height + offset_y)
        if out_of_space:
            break
        max_y = max(y + character_height + offset_y, max_y)
        draw.text(xy=(x, y), text=character, fill=color + (255, ), font=font)
        for subcharacter in subcharacters:
            lines[-1].append(
                (np.array([[x + offset_x, y + offset_y],
                           [x + dx + offset_x, y + offset_y],
                           [x + dx + offset_x, y2],
                           [x + offset_x,
                            y2]]).astype('float32'), subcharacter))
            sentence += subcharacter
            x += dx
    image = cv2.warpPerspective(src=np.array(image),
                                M=M,
                                dsize=(width, height))
    if draw_contour:
        image = cv2.drawContours(
            image,
            contours=[permitted_contour.reshape((-1, 1, 2)).astype('int32')],
            contourIdx=0,
            color=(255, 0, 0, 255),
            thickness=int(width / 100))
    lines = strip_lines(lines)
    lines = [[(cv2.perspectiveTransform(src=coords[np.newaxis],
                                        m=M)[0], character)
              for coords, character in line] for line in lines]
    return image, sentence, lines
Exemple #42
0
MIN_MATCH_COUNT = 10
if len(good) > MIN_MATCH_COUNT:

    # Get positions of matched points
    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)

    # Get perspective transformation matrix and list of inliers and outliers
    M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
    matchesMask = mask.ravel().tolist()

    # Project the object points into image frame
    h, w = img1.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)

    # Draw box
    img2 = cv2.polylines(img2, [np.int32(dst)], True, 255, 3, cv2.LINE_AA)

else:
    print("Not enough matches are found - %d/%d" %
          (len(good), MIN_MATCH_COUNT))
    matchesMask = None

draw_params = dict(
    matchColor=(0, 255, 0),  # draw matches in green color
    singlePointColor=None,
    matchesMask=matchesMask,  # draw only inliers
    flags=2)
Exemple #43
0
def main(argv):

	if len(argv) < 5:
		print 'Error, incorrect number of args:\n python dataset_path max_number_images number_transformations patch_size\n'
		sys.exit(1)

	if not os.path.exists(outImPath):
		os.mkdir(outImPath)

	imDatasetPath = argv[1]  # Dir that contains the original images
	maxImg = int(argv[2])
	numWarps = int(argv[3]) # number of warps per image
	patchSize =  int(argv[4]) # patch size 

	# create file
	fileList = open(trainFilename,'w') 
	imFiles = [f for f in listdir(imDatasetPath) if isfile(join(imDatasetPath, f))]

	numIm = 0
	for imFile in imFiles:
		if numIm >= maxImg:
			sys.exit(1)
		# Read image
		img = cv2.imread(imDatasetPath + imFile, 0)
		if not img is None:

			# for each 
			height, width = img.shape[:2]
			if height > patchSize * 3 and width > patchSize * 3:
				print str(numIm), ' Load: ', imDatasetPath + imFile
				x1 = (width/2)- (patchSize/2)
				x2 = (width/2) + patchSize/2
				y1 = (height/2)- (patchSize/2)
				y2 = (height/2) + patchSize/2

				patchLocation = np.float32( [ [x1, y1], [x2, y1], [x2, y2], [x1, y2]])
				patchLocation = np.array([patchLocation])
				patch_I1 = img[y1:y2, x1:x2] # Crop from x, y, w, h -> 100, 200, 300, 400
				namePatchI1 = outImPath + str(numIm) + '_I1' + '.png'
				cv2.imwrite( namePatchI1, patch_I1)	

				for nW in range(0, numWarps):
					# Perform several transformations for the same image, 
					# in order to make the network learn different corner outputs
					# from the same patch I1

					# Extract a patch in the center of size 128x128
					# Perform the 4-corner perspective change!
					warpImg, Hom = affine_transform(patchSize, img, width, height, 0.05)		
					patchHom = cv2.perspectiveTransform(patchLocation, Hom)

					# Generate some extra offset on the I2 coordinates
					# This factor will make the extra margin on I2 bigger
					randomDispFactor = 0.7
					x1_off = int(round(randomDispFactor * patchSize))  * (random.uniform(1, 100) / 100)
					x2_off = int(round(randomDispFactor * patchSize))  * (random.uniform(1, 100) / 100)
					y1_off = x1_off
					y2_off = x2_off
					#y1_off = int(round(randomDispFactor * patchSize))  * (random.uniform(1, 100) / 100)
					#y2_off = int(round(randomDispFactor * patchSize))  * (random.uniform(1, 100) / 100)

					patchHom[0][0][0] = patchHom[0][0][0] - x1_off
					patchHom[0][0][1] = patchHom[0][0][1] - y1_off
					patchHom[0][1][0] = patchHom[0][1][0] + x2_off
					patchHom[0][1][1] = patchHom[0][1][1] - y1_off
					patchHom[0][2][0] = patchHom[0][2][0] + x2_off
					patchHom[0][2][1] = patchHom[0][2][1] + y2_off
					patchHom[0][3][0] = patchHom[0][3][0] - x1_off
					patchHom[0][3][1] = patchHom[0][3][1] + y2_off
					
					xh1, yh1 = patchHom[0].min(0)
					xh2, yh2 = patchHom[0].max(0)
					xh1 = int(round(xh1))
					xh2 = int(round(xh2))
					yh1 = int(round(yh1))
					yh2 = int(round(yh2))

					#print '\n Y[', yh1, ':', yh2, ']  X [', xh1, ':', xh2, ']'
					patch_I2 = warpImg[yh1:yh2, xh1:xh2]
					wh = xh2 - xh1
					hh = yh2 - yh1

					gtCorner = np.float32([[1, 1], [1, 1], [1, 1], [1, 1]])
					gtCorner[0] = np.float32([(patchHom[0][0][0] - xh1) + x1_off     , (patchHom[0][0][1] - yh1) + y1_off])
					gtCorner[1] = np.float32([wh - (xh2 - patchHom[0][1][0]) - x2_off, (patchHom[0][1][1] - yh1) + y1_off])
					gtCorner[2] = np.float32([wh - (xh2 - patchHom[0][2][0]) - x2_off, hh - (yh2 - patchHom[0][2][1]) - y2_off])
					gtCorner[3] = np.float32([(patchHom[0][3][0] - xh1) + x1_off     , hh - (yh2 - patchHom[0][3][1]) - y2_off])

					fs_x = float(patchSize) / float(wh)
					fs_y = float(patchSize) / float(hh)
					for p in range(0, 4):
						gtCorner[p][0] = int(round(gtCorner[p][0] * fs_x))
						gtCorner[p][1] = int(round(gtCorner[p][1] * fs_y))

					# Scale patch_I2 to patchSize and adjust the gtCorners!
					patch_I2 = cv2.resize(patch_I2, (patchSize, patchSize))

					# TODO Apply more changes:
					# - Blurring
					# - Illumination 
					# - Occlusion??
					# - ...
					
					# Export patch warp
					namePatchI2 = outImPath + str(numIm) + '_I' + str(nW + 2) + '.png'
					cv2.imwrite( namePatchI2, patch_I2)	

					# add line to file
					fileList.write( namePatchI1 + ' ' + namePatchI2)
					gtCorner = gtCorner / patchSize
					for p in range(0, 4):
						
						fileList.write(' ' + str(gtCorner[p][0]) + ' ' + str(gtCorner[p][1]))
					fileList.write('\n')

					if verbose:
						cv2.polylines(img,  np.int32(patchLocation), 1, 255, 7)
						cv2.polylines(warpImg,  np.int32(patchHom), 1, 0, 4)
						#cv2.imshow('full image', img)
						#cv2.imshow('full image warped', warpImg)

						for p in range(0, 4):	
							print p, ': ', gtCorner[p] 
							cv2.circle(patch_I2, (int(round(gtCorner[p][0] * patchSize)), int(round(gtCorner[p][1] * patchSize))), 5, 255, 1)

						cv2.imshow('I1', patch_I1)
						cv2.imshow('I2', patch_I2)
						cv2.waitKey(0)
						cv2.destroyAllWindows()

				numIm = numIm + 1

	fileList.close()
        """
        End of:
        Non-maximum suppression
        """
 
        """
        Start of:
        Data extraction
        """
        # Confirm data structure for points
        points = np.asarray(points, dtype=np.float32)
        points = np.array([points])
        
        # Warp for coordinate projection
        warped, M_geo = transf.four_point_transform_geo(frame, corners, corners_geo)
        pointsOut = cv2.perspectiveTransform(points, M_geo)
        pointsOut = pointsOut.tolist()[0]
        
        # Create dataframe for frame and append it
        i_df = mapping.adjustDataFrame(df, pointsOut, class_type, f)
        df = df.append(i_df)

        """
        End of:
        Data extraction
        """
 
    else:
        continue

"""
Exemple #45
0
    contours
)  # duplicate contours list and remove any contours that are too short

for cont in range(len(contours)):
    if len(contours[cont]) < 19:
        contours_shorten.remove(contours[cont])

contour_pertr = []  # perspective correction contours
contours_pertrInts = []

for cont3 in range(len(contours_shorten)):
    contours_shorten[cont3] = contours_shorten[cont3].reshape(-1, 2)
    a = contours_shorten[cont3]
    a = np.array([a])
    a = a.astype(float)
    contour_pertr.append(cv2.perspectiveTransform(a, h))
    contour_pertr[cont3] = np.reshape(np.ravel(contour_pertr[cont3]),
                                      (-1, 1, 2))
    contour_pertr[cont3] = np.reshape(np.ravel(contour_pertr[cont3]), (-1, 2))
    contours_pertrInts.append(cv2.perspectiveTransform(a, h))
    contours_pertrInts[cont3] = np.reshape(np.ravel(contours_pertrInts[cont3]),
                                           (-1, 1, 2))
    contours_pertrInts[cont3] = np.reshape(np.ravel(contours_pertrInts[cont3]),
                                           (-1, 2))
    contours_pertrInts[cont3] = contours_pertrInts[cont3].astype(int)
    #for ind in range(2):
    #    contours_pertrInts[cont3][cont_pertr][ind] = int(contour_pertr[cont3][cont_pertr][ind])
    #contours_pertrInts[cont3] = np.reshape(np.ravel(contours_pertrInts[cont3]),(-1,1,2))
    #contours_pertrInts[cont3].astype(int)
    #contour_pertr[cont3] = np.reshape(np.ravel(contour_pertr[cont3]),(-1,1,2))
    #contours_shorten[cont3] = a.reshape(-1,1,2)
Exemple #46
0
    M = cv2.getPerspectiveTransform(pts1, pts2)
    # 进行透视变换
    # dst = cv2.warpPerspective(img,M,(300,300))
    return M


img = cv2.imread(r'C:\temp\pad.jpg')
h, w = img.shape[:2]
ps = [(0, 0), (w - 1, 0), (w - 1, h - 1), (0, h - 1)]
pM = get_perspective_matrix(img, ps)
# inner = cv2.perspectiveTransform(np.array([[inner]]), pM, (target_w, target_h))
img = cv2.warpPerspective(img, pM, (w, h))

# cv2.imshow('adsf', img)
# cv2.waitKey(0)
# cv2.imwrite(r'C:\temp\pad2.jpg', img)

# old_points = [328, 124]
a = np.array([[328, 124], [348, 120], [118, 178], [690, 86]], dtype='float32')
print('shape: ', a.shape)
# h = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype='float32')
a = np.array([a])
print('shape: ', a.shape)

pointsOut = cv2.perspectiveTransform(a, pM)

print(type(pointsOut))
print(pointsOut)
print(pointsOut.shape)
print(pointsOut[0][1][0])
print(pointsOut[0][1][1])
    def print_court_polylines(best_homography_matrix):

        for line in BadmintonCourt.court_lines():
            pts = np.float32([line]).reshape(-1, 1, 2)
            dst = cv2.perspectiveTransform(pts, best_homography_matrix)
            draw.line([(dst[0][0][0], dst[0][0][1]), (dst[1][0][0], dst[1][0][1])],fill="red")
Exemple #48
0
def find_matches(pic1, pic2):
    MIN_MATCH_COUNT = 10

    img1 = cv2.imread(pic1, 0)
    print('img1', np.shape(img1))
    img2 = cv2.imread(pic2, 0)
    print('img2', np.shape(img2))

    #Feature detection by adaptive ROI
    # Initiate SIFT detector
    sift = cv2.xfeatures2d.SIFT_create()
    print('sift', np.shape(sift))

    # find the keypoints and descriptors with SIFT
    kp1, des1 = sift.detectAndCompute(img1, None)
    print('kp1', np.shape(kp1))
    print('des1', np.shape(des1))
    kp2, des2 = sift.detectAndCompute(img2, None)
    print('kp2', np.shape(kp2))
    print('des2', np.shape(des2))

    FLANN_INDEX_KDTREE = 0
    index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
    search_params = dict(checks=50)

    #create FLANN Matcher object
    #matches the targets between two images
    flann = cv2.FlannBasedMatcher(index_params, search_params)
    print('flann', np.shape(flann))

    #Match descriptors
    matches = flann.knnMatch(des1, des2, k=2)
    print('matches', np.shape(matches))

    # store all the good matches as per Lowe's ratio test.
    good = []
    for m, n in matches:
        if m.distance < 0.7 * n.distance:
            good.append(m)

    if len(good) > MIN_MATCH_COUNT:
        #feature detections
        img1_pts = np.float32([kp1[m.queryIdx].pt for m in good
                               ]).reshape(-1, 1,
                                          2)  #matched pt locations in image 1
        print('img1_pts', np.shape(img1_pts))
        img2_pts = np.float32([kp2[m.trainIdx].pt for m in good
                               ]).reshape(-1, 1,
                                          2)  #matched pt locations in image 2
        print('img2_pts', np.shape(img2_pts))

        #calculate homography before or after displacements?
        H, mask = cv2.findHomography(img1_pts, img2_pts, cv2.RANSAC,
                                     5.0)  #H is 3x3 homography matrix
        matchesMask = mask.ravel().tolist()
        print('H', np.shape(H))
        print('mask', np.shape(mask))
        print('matchesMask', np.shape(matchesMask))

        #feature image coord displacements
        displacements = []
        for i in range(len(img1_pts)):
            disp = math.sqrt(
                (img1_pts[i][0][0] - img2_pts[i][0][0])**2 +
                (img1_pts[i][0][1] - img2_pts[i][0][1])**2)  #distance formula
            displacements.append(disp)

        print('displacements', np.shape(displacements))

        height, width = img1.shape
        pts = np.float32([[0, 0], [0, height - 1], [width - 1, height - 1],
                          [width - 1, 0]]).reshape(-1, 1, 2)
        dst = cv2.perspectiveTransform(pts, H)
        print('pts', np.shape(pts))
        print('dst', np.shape(dst))

        img2 = cv2.polylines(img2, [np.int32(dst)], True, 255, 3, cv2.LINE_AA)

    else:
        print("Not enough matches are found - %d/%d" %
              (len(good), MIN_MATCH_COUNT))
        matchesMask = None

    draw_params = dict(
        matchColor=(0, 255, 0),  # draw matches in green color
        singlePointColor=False,
        matchesMask=matchesMask,  # draw only inliers
        flags=2)

    #img3 = cv2.drawMatches(img1,kp1,img2,kp2,good,None,**dr0000aw_params)

    #return homography transform matrix H and image coordinate displacement vector
    return [H, mask, good, img1_pts, displacements
            ]  #change name; what *type* of displacements are these
Exemple #49
0
    if frame_num == 1:
        # Pida al usuario que marque puntos paralelos y dos puntos separados por 6 pies. Orden bl, br, tr, tl, p1, p2
        while True:
            image = frame
            cv2.imshow("image", image)
            cv2.waitKey(1)
            if len(mouse_pts) == 7:
                cv2.destroyWindow("image")
                break
            first_frame_display = False
        four_points = mouse_pts

        # Obtener perspectiva
        M, Minv = get_camera_perspective(frame, four_points[0:4])
        pts = src = np.float32(np.array([four_points[4:]]))
        warped_pt = cv2.perspectiveTransform(pts, M)[0]
        d_thresh = np.sqrt(
            (warped_pt[0][0] - warped_pt[1][0]) ** 2
            + (warped_pt[0][1] - warped_pt[1][1]) ** 2
        )
        bird_image = np.zeros(
            (int(frame_h * scale_h), int(frame_w * scale_w), 3), np.uint8
        )

        bird_image[:] = SOLID_BACK_COLOR
        pedestrian_detect = frame

    print("Procesando fotograma: ", frame_num)

    # Se dibuja el polígono de ROI(región binaria de interés)
    pts = np.array(
Exemple #50
0
        good_points.append(m)

print("Done comparing matches - retained %2d" % len(good_points))

draw_params = dict(matchColor = (0,255,0),
                   singlePointColor = (255,0,0),
                   matchesMask = matchesMask,
                   flags = 0)

img3 = cv2.drawMatchesKnn(img,kp_image,img2,kp_image2,matches,None,**draw_params)
cv2.imshow("Matches",img3)

query_pts = np.float32([kp_image[m.queryIdx].pt for m in good_points]).reshape(-1, 1, 2)
train_pts = np.float32([kp_image2[m.trainIdx].pt for m in good_points]).reshape(-1, 1, 2)
matrix, mask = cv2.findHomography(query_pts, train_pts, cv2.RANSAC, 5.0)
print("Homography found %2d %2d" % (len(query_pts),len(train_pts)))
matches_mask = mask.ravel().tolist()

# Perspective transform
h, w = img.shape
pts = np.float32([[0, 0], [0, h], [w, h], [w, 0]]).reshape(-1, 1, 2)
dst = cv2.perspectiveTransform(pts, matrix)

homography = cv2.polylines(img2, [np.int32(dst)], True, (255, 0, 0), 3)

# Plot the keypoints used
kp_used = [kp_image2[m.trainIdx] for m in good_points];
img3=cv2.drawKeypoints(homography, kp_used, None)
cv2.imshow("Homography",img3)
cv2.waitKey()
Exemple #51
0
    def get_homography(self, img1, img2, plot=False, rigid=True):
        """Compute a homography between two images"""
        if isinstance(img1, np.ndarray) and isinstance(img2, np.ndarray):
            pass
        elif isinstance(img1, basestring) and isinstance(img2, basestring):
            img1 = cv2.imread(img1)
            img2 = cv2.imread(img2)
        else:
            msg = 'Unsupported type; use numpy.ndarray or string'
            raise RuntimeError(msg)

        img1gray = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
        img2gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)

        # Find descriptors in each image
        kp1, des1 = self.feature_detection.detectAndCompute(img1gray, None)
        kp2, des2 = self.feature_detection.detectAndCompute(img2gray, None)

        # Match descriptors between images
        matches = self.matcher.knnMatch(des1, des2, k=2)

        # Store all the good matches as per Lowe's ratio test.
        good = []
        for m, n in matches:
            if m.distance < 0.7 * n.distance:
                good.append(m)

        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)

        if rigid:
            full_affine = False
            M = cv2.estimateRigidTransform(src_pts, dst_pts, full_affine)
            if M is None:
                raise RuntimeError('Could not estimate rigid transform.')
            M = np.vstack((M, np.eye(1, 3, 2)))
        else:
            M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)

        if plot:
            if not rigid:
                matchesMask = mask.ravel().tolist()

                h, w = img1gray.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)

                # Draw matches in green (only inliers)
                draw_params = dict(matchColor=(0, 255, 0),
                                   singlePointColor=None,
                                   matchesMask=matchesMask,
                                   flags=2)

                img3 = cv2.drawMatches(img1, kp1, img2, kp2, good, None,
                                       **draw_params)

                plt.figure()
                plt.imshow(img3)

            # Draw stitching
            stitch = self.warp_two_images(img1, img2, np.linalg.inv(M))
            plt.imshow(stitch)

            plt.show()
        return M
Exemple #52
0
def main():
    """
    This functions loads the target surface image,
    """
    homography = None

    camera_parameters = mtx  # got after doing the caliberation
    # camera_parameters = np.array([[800, 0, 320], [0, 800, 240], [0, 0, 1]])
    # create ORB keypoint detector
    sift = cv2.xfeatures2d.SIFT_create()
    # create BFMatcher object based on hamming distance
    bf = cv2.BFMatcher()
    # load the reference surface that will be searched in the video stream
    dir_name = os.getcwd()
    marker1 = cv2.imread(
        os.path.join(dir_name, 'reference/markers/marker1.jpg'), 0)
    marker1_inverse = cv2.imread(
        os.path.join(dir_name, 'reference/markers/marker1_inverse.jpg'), 0)
    # Compute marker keypoints and its descriptors
    kp_marker1 = sift.detect(marker1, None)
    kp_marker1, des_marker1 = sift.compute(marker1, kp_marker1)

    kp_marker1_inverse = sift.detect(marker1_inverse, None)
    kp_marker1_inverse, des_marker1_inverse = sift.compute(
        marker1_inverse, kp_marker1_inverse)

    # Load 3D model from OBJ file
    obj = OBJ(os.path.join(dir_name, 'models/fox.obj'), swapyz=True)
    # init video capture

    # cap = cv2.VideoCapture(0)
    cap = cv2.VideoCapture("./reference/videos/test_1.mp4")

    prev5 = np.ones((3, 3))
    prev4 = np.ones((3, 3))
    prev3 = np.ones((3, 3))
    prev2 = np.ones((3, 3))
    prev1 = np.ones((3, 3))
    homography = np.ones((3, 3))

    prev_5 = np.ones((3, 3))
    prev_4 = np.ones((3, 3))
    prev_3 = np.ones((3, 3))
    prev_2 = np.ones((3, 3))
    prev_1 = np.ones((3, 3))
    homography_2 = np.ones((3, 3))

    speed = 10
    Identity = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
    unit_translation = np.array([[0, 0, 0], [0, 0, 1], [0, 0, 0]])
    prev_trans = np.array([[0, 0, 0], [0, 0, 1], [0, 0, 0]])

    center1 = np.array([0, 0])

    n_frame = 0
    inverse = False

    cv2.namedWindow("window", cv2.WND_PROP_FULLSCREEN)
    cv2.setWindowProperty("window", cv2.WND_PROP_FULLSCREEN,
                          cv2.WINDOW_FULLSCREEN)

    while True:

        n_frame += 1
        # read the current frame
        ret, frame = cap.read()
        if not ret:
            print("Unable to capture video")
            return

        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        ret, corners_c = cv2.findChessboardCorners(gray, (9, 6), None)
        # objpoints.append(objp)
        if ret == True:
            h, w = 6, 9
            corners_chess = cv2.cornerSubPix(gray, corners_c, (11, 11),
                                             (-1, -1), criteria)
            # imgpoints.append(corners_chess)
            homography_chess, mask = cv2.findHomography(
                objp, corners_chess, cv2.RANSAC, 5.0)
            pts_chess = np.float32([[0, 0], [0, h - 1], [w - 1, h - 1],
                                    [w - 1, 0]]).reshape(-1, 1, 2)
            pts_chess = pts_chess * square_size
            dst_chess = cv2.perspectiveTransform(pts_chess, homography_chess)
            frame = cv2.polylines(frame, [np.int32(dst_chess)], True, 200, 3,
                                  cv2.LINE_AA)
            # print(homography_chess)
            # Draw and display the corners
            frame = cv2.drawChessboardCorners(frame, (9, 6), corners_chess,
                                              ret)
            if (point_inside(center1, dst_chess)):
                cv2.waitKey(2000)
                # speed *= -1
                print("Reached destination !!")
                inverse = not inverse
                print("What to do ????")
                prev_trans *= -1
                print("Better I go back ...")

        if inverse:
            desMark1 = des_marker1_inverse
            kpMark1 = kp_marker1_inverse
        else:
            desMark1 = des_marker1
            kpMark1 = kp_marker1

        # find and draw the keypoints of the frame
        kp_frame = sift.detect(frame, None)
        kp_frame, des_frame = sift.compute(frame, kp_frame)
        matches1 = bf.knnMatch(desMark1, des_frame, k=2)
        # match frame descriptors with model descriptors
        # sort them in the order of their distance
        # the lower the distance, the better the matc h

        good = []
        for m in matches1:
            if m[0].distance < 0.75 * m[1].distance:
                good.append(m)
        matches1 = np.asarray(good)
        # print(len(matches))

        # compute Homography if enough matches are found
        if len(matches1) > MIN_MATCHES:
            # differenciate between source points and destination points
            src_pts = np.float32([kpMark1[m[0].queryIdx].pt
                                  for m in matches1]).reshape(-1, 1, 2)
            dst_pts = np.float32([
                kp_frame[m[0].trainIdx].pt for m in matches1
            ]).reshape(-1, 1, 2)
            # compute Homography

            prev5 = prev4
            prev4 = prev3
            prev3 = prev2
            prev2 = prev1
            prev1 = homography
            homography, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC,
                                                  5.0)
            try:
                avg_homography = (prev1 + prev2 + prev3 + prev4 + prev5 +
                                  homography) / 6.0
            except:
                continue
            # avg_homography = homography

            if True:
                # Draw a rectangle that marks the found model in the frame
                h, w = marker1.shape

                pts = np.float32([[0, 0], [0, h - 1], [w - 1, h - 1],
                                  [w - 1, 0]]).reshape(-1, 1, 2)
                center = (pts[0] + pts[1] + pts[2] + pts[3]) / 4
                # project corners into frame
                dst1 = cv2.perspectiveTransform(pts, avg_homography)
                # connect them with lines
                frame = cv2.polylines(frame, [np.int32(dst1)], True, 255, 3,
                                      cv2.LINE_AA)
            # if a valid homography matrix was found render cube on model plane
            if homography is not None:
                try:
                    # obtain 3D projection matrix from homography matrix and camera parameters
                    # avg_homography = np.matmul(Identity,avg_homography)
                    avg_homography = np.matmul(
                        avg_homography,
                        Identity + prev_trans + unit_translation * speed)
                    prev_trans = prev_trans + unit_translation * speed
                    dst1 = cv2.perspectiveTransform(pts, avg_homography)
                    center1 = (dst1[0] + dst1[1] + dst1[2] +
                               dst1[3]) / 4  # img coordinates
                    frame = cv2.polylines(frame, [np.int32(dst1)], True, 255,
                                          3, cv2.LINE_AA)
                    # frame = cv2.circle(frame, [np.int32(center)], True, 255, 3, cv2.LINE_AA)
                    projection = projection_matrix(camera_parameters,
                                                   avg_homography)
                    # project cube or model
                    frame = render(frame, obj, projection, marker1, False)

                    #frame = render(frame, model, projection)
                except Exception as e:
                    print(e)
            cv2.imshow('window', frame)
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break  # draw first 10 matches1.

        else:
            print("Not enough matches found - %d/%d" %
                  (len(matches1), MIN_MATCHES))

    cap.release()
    cv2.destroyAllWindows()
    return 0
Exemple #53
0
    def detect(
                self,
                object_name: str,
                query_img_feat: list,
                sensor_image: np.ndarray
            ):
        """
        Detects if the object is in the frame

        Parameters
        ----------
        object_name : str
            Name of the object.
        query_img_feat : list
            A list containing keypoints, descriptors, and
            dimension information of query object's image
        sensor_image : numpy.ndarray
            Image retrieved from a sensor (webcam/kinect).
        """
        MIN_MATCH_COUNT = self.config.min_match_count
        # If True the frame with detected object will
        # be showed, by default False
        show_image = self.config.show_image
        if self.to_gray:
            # sensor_rgb = sensor_image
            sensor_image = cv2.cvtColor(sensor_image, cv2.COLOR_BGR2GRAY)

        kp1, des1, dim = query_img_feat
        kp2, des2 = self.detector_descriptor.detectAndCompute(sensor_image, None)  # noqa: E501

        matches = self.matcher(des1, des2, **self.config.matcher_kwargs)
        # store all the good matches as per Lowe's ratio test.
        good = []
        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, _ = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)

            if M is None:
                return

            h, w = dim
            pts = np.float32(
                    [[0, 0], [0, h-1], [w-1, h-1], [w-1, 0]]
                ).reshape(-1, 1, 2)
            dst = cv2.perspectiveTransform(pts, M).astype(np.int32)
            # update the location of the object in the image
            # converted to list as ndarray object is not json serializable
            self.obj_boundary_info[object_name] = np.squeeze(dst, axis=1).tolist()  # noqa: E501

            if self.config.hold_prev_vals:
                self.object_timer[object_name] = time()

            if show_image:
                # sensor_rgb = cv2.polylines(sensor_rgb, [dst] ,True,255,1, cv2.LINE_AA)  # noqa: E501
                self.viz_frame = self.annotate_frame(
                                            self.viz_frame,
                                            dst,
                                            object_name
                                        )

        else:
            if self.config.hold_prev_vals:
                if time() - self.object_timer[object_name] > self.config.hold_period:  # noqa: E501
                    self.obj_boundary_info[object_name] = None
                else:
                    if self.config.show_image and object_name in self.obj_boundary_info.keys():  # noqa: E501
                        self.viz_frame = self.annotate_frame(
                                            self.viz_frame,
                                            np.expand_dims(
                                                np.array(self.obj_boundary_info[object_name], dtype=np.int32),  # noqa: E501
                                                axis=1
                                            ),
                                            object_name
                                        )
            else:
                # Set None if the object isn't detected
                self.obj_boundary_info[object_name] = None
                rospy.loginfo("Not enough matches are found - {}/{}".format(len(good), MIN_MATCH_COUNT))  # noqa: E501
Exemple #54
0
def circleposition(cap, transform, newcameramtx, mtx, dist, mask, maskcorners):
    thresh = 0
    maxValue = 255
    #print "CAP type" + str(type(cap))
    [oldx, oldy] = [0, 0]
    #print "maskcorners %s" % str(maskcorners)
    params = cv2.SimpleBlobDetector_Params()

    # Change thresholds
    #params.minThreshold = 10;
    #params.maxThreshold = 200;

    # Filter by Area.
    params.filterByArea = True
    params.minArea = 125
    params.maxArea = 375

    # Filter by Circularity
    #params.filterByCircularity = True
    #params.minCircularity = 0.8

    # Filter by Convexity
    params.filterByConvexity = True
    params.minConvexity = 0.87

    # Filter by Inertia
    #params.filterByInertia = True
    #params.minInertiaRatio = 0.01
    ret, frame = cap.read()
    detector = cv2.SimpleBlobDetector_create(params)
    h, w = frame.shape[:2]
    done = False
    l = [[1, 1], [1, 1], [1, 1]]
    while True:
        time1 = time.clock()
        ret, frame = cap.read()
        if frame is None:
            return

        frame = cv2.undistort(frame, mtx, dist, None, newcameramtx)
        ffframe = cv2.flip(frame, -1)

        ulx = maskcorners[0][0] - 20  ##sorg for ikke at ryge udenfor billede
        uly = maskcorners[0][1] - 20
        brx = maskcorners[2][0] + 20
        bry = maskcorners[2][1] + 20

        ffframe = ffframe[uly:bry, ulx:brx]

        gray = cv2.cvtColor(ffframe, cv2.COLOR_BGR2GRAY)

        th, dst = cv2.threshold(gray, thresh, maxValue,
                                cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

        # Detect blobs.
        dtime1 = time.clock()
        keypoints = detector.detect(dst)
        dtime2 = time.clock()
        #print('detector %0.6f' % (dtime2-dtime1))
        #print "keypoints" + str(keypoints)

        #for k in keypoints:
        #    print("respovce {}".format(k.response))

        if len(keypoints) > 0:
            keypoint = [keypoints[-1]]
        else:
            keypoint = None

        #print "keypoint" + str(keypoint)
        if keypoint is not None:
            #print keypoint[0].pt
            circle = keypoint[0].pt
            #circlesize = keypoint[0].size
            #print("Size {}".format(keypoint[0].size))
            #cv2.waitKey(5000)
            #print "im alive"
            im_with_keypoints = cv2.drawKeypoints(
                ffframe, keypoints, np.array([]), (0, 0, 255),
                cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
            cv2.imshow("im_with_keypoints", im_with_keypoints)
            #cv2.imshow("out", out)

            #cv2.waitKey(1)
            print("point diff")
            print(np.absolute(circle[0] - l[2][0]))
            print(np.absolute(circle[1] - l[2][1]))
            #if (np.absolute(c) > 12 or np.absolute(circle[1]-l[2][1]) > 12): ## and (np.absolute(circle[0]-l[2][0]) < 100 or np.absolute(circle[1]-l[2][1]) < 100):
            l.append([int(circle[0] + ulx), int(circle[1] + uly)])
            l = l[1:]
            #else:
            #    raise Exception("hej")
        else:
            print("else")
            continue

        adpoint = np.array(l[2], dtype='float32')
        point = np.array([[l[2]]], dtype='float32')
        pointOut = cv2.perspectiveTransform(point, transform)

        [[[xo, yo]]] = pointOut

        time2 = time.clock()
        print('findcircle clocktime %0.6f' % (time2 - time1))

        yield [xo, yo, im_with_keypoints, keypoint[0].size]
Exemple #55
0
    src_pts = np.float32([k1[m.queryIdx].pt for m in good]).reshape(-1, 1, 2)
    dst_pts = np.float32([k2[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)

    M, mask = cv2.findHomography(dst_pts, src_pts, cv2.RANSAC, 5.0)
    matchesMask = mask.ravel().tolist()

else:
    print "not enough matches are found - %d%d" % (len(good), MIN_MATCH_COUNT)
    matchesMask = None

rows, cols = img1.shape
pts2 = M
pts1 = np.float32([[0, 0], [0, rows - 1], [cols - 1, rows - 1],
                   [cols - 1, 0]]).reshape(-1, 1,
                                           2)  #where the points will be warped
d = cv2.perspectiveTransform(pts1, pts2)
#out = cv2.polylines(img2, [np.int32(d)], True,255,3)
warp = cv2.warpPerspective(img2, M,
                           (cols, rows))  #warp Image 2 to Image 1 coordinates

#visualizations
h1, w1 = img1.shape[:2]
h2, w2 = img2.shape[:2]
view = sp.zeros((max(h1, h2), w1 + w2, 3), sp.uint8)

view[:h1, :w1, 0] = img1
view[:h2, w1:, 0] = img2
view[:, :, 1] = view[:, :, 0]
view[:, :, 2] = view[:, :, 0]

cols1 = img1.shape[1]
Exemple #56
0
    def cam_image_cb(self, data):
        try:
            cv_image = self.bridge.compressed_imgmsg_to_cv2(
                data, self.encoding)
            #cv_image = self.bridge.imgmsg_to_cv2(data), self.encoding)
        except CvBridgeError as e:
            print(e)
            return

        # Create a copy of the image to publish
        cv_image2 = cv_image.copy()

        # Change the image to Grayscale
        cv_image_gray = cv2.cvtColor(cv_image.copy(), cv2.COLOR_BGR2GRAY)

        # find the keypoints with ORB
        kp_Scene, des_Scene = self.orb.detectAndCompute(cv_image_gray, None)

        # Match features
        if (len(kp_Scene) > 0):
            matches = self.matcher.match(self.des_Object, des_Scene)
            matches_sorted = sorted(matches, key=lambda x: x.distance)
        else:
            return

        # If number of matches is greater than threshold find the location of the object in the scene
        if len(matches_sorted) > self.MIN_MATCH_COUNT:
            src_pts = np.float32([
                self.kp_Object[m.queryIdx].pt for m in matches_sorted
            ]).reshape(-1, 1, 2)
            dst_pts = np.float32([
                kp_Scene[m.trainIdx].pt for m in matches_sorted
            ]).reshape(-1, 1, 2)
            M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)

            # Corners of object
            h, w = self.imgObject.shape[:2]
            pts = np.float32([[0, 0], [0, h - 1], [w - 1, h - 1],
                              [w - 1, 0]]).reshape(-1, 1, 2)

            # Corners of detected object
            dst = cv2.perspectiveTransform(pts, M).reshape(4, 2)

            # Corners of GOAL image
            h, w = self.imgGoal.shape[:2]
            pts = np.array([[0, 0], [0, h - 1], [w - 1, h - 1], [w - 1, 0]],
                           dtype="float32")

            # Get perspective transform
            transf = cv2.getPerspectiveTransform(pts, dst)
            h, w = cv_image2.shape[:2]
            warp = cv2.warpPerspective(self.imgGoal, transf, (w, h))

            cv_image2 = cv2.fillPoly(cv_image2,
                                     [np.int32(dst).reshape((-1, 1, 2))],
                                     (0, 0, 0))  # Remove object in scene
            cv_image2 = cv2.add(cv_image2, warp)  # Draw new image

            #-- Draw Bounding box
            #cv_image2 = cv2.polylines(cv_image2, [np.int32(dst).reshape((-1, 1, 2))] , True, (0,0,255),3, cv2.LINE_AA)

        try:
            #self.image_pub.publish(self.bridge.cv2_to_compressed_imgmsg(cv_image2))
            self.image_pub.publish(self.bridge.cv2_to_imgmsg(
                cv_image2, "bgr8"))
        except CvBridgeError as e:
            print(e)
Exemple #57
0
def combine_images(img0, img1, h_matrix):
    # print('拼接图像... ')

    points0 = np.array(
        [[0, 0], [0, img0.shape[0]], [img0.shape[1], img0.shape[0]], [img0.shape[1], 0]], dtype=np.float32)
    points0 = points0.reshape((-1, 1, 2))
    points1 = np.array(
        [[0, 0], [0, img1.shape[0]], [img1.shape[1], img0.shape[0]], [img1.shape[1], 0]], dtype=np.float32)
    points1 = points1.reshape((-1, 1, 2))
    points2 = cv2.perspectiveTransform(points1, h_matrix)
    points = np.concatenate((points0, points2), axis=0)
    [x_min, y_min] = np.int32(points.min(axis=0).ravel() - 0.5)
    [x_max, y_max] = np.int32(points.max(axis=0).ravel() + 0.5)

    # print('points2:', points2[0][0][0])
    # print('points2:', points2[1][0][0])
    # 重叠区域的左边界,开始位置
    start = min(points2[0][0][0], points2[1][0][0])
    # 重叠区域的宽度
    width = img0.shape[1] - start
    # img1中像素的权重
    alpha = 1
    # print('start:',start)
    # print('width:',width)
    # print('img0[0]:', img0[0][0][0])

    #('xmin:', x_min, 'xmax', x_max, 'ymin', y_min, 'ymax', y_max)
    H_translation = np.array([[1, 0, -x_min], [0, 1, -y_min], [0, 0, 1]])
    # print('单应性矩阵Homography:', h_matrix)
    # print('WARP右图...')
    # cv2.imshow('img0', img0)

    # img0是左图
    cv2.imshow('img1', img0)

    # output_img暂时是经过变换之后的右图
    output_img = cv2.warpPerspective(img1, H_translation.dot(h_matrix), (x_max - x_min, y_max - y_min),
                                     borderMode=cv2.BORDER_TRANSPARENT)
    #cv2.imwrite('img2.jpg', output_img)
    cv2.imshow('warped', output_img)
    H_img1 = output_img.copy()

    # 拷贝左图的0到start之内的到右图上
    H_img1[:img0.shape[0], :int(start)] = img0[:img0.shape[0], :int(start)]
    output_size = output_img.shape
    cv2.imshow('H_img1', H_img1)
    # print(output_size)
    x_offset = x_max - img1.shape[0]
    # y_offset = y_max-img1.shape[1]

    # 要将左图无缝地加入到变换过后的右图上
    # force combine them together
    output_img[-y_min:img0.shape[0] - y_min,
               - x_min:img0.shape[1] - x_min] = img0

    tmp_r = H_img1[0:y_max, x_max - x_offset:x_max]
    tmp_l = output_img[0:y_max, 0:img0.shape[1]]
    #cv2.imwrite('img1.jpg', output_img)
    # cv2.waitKey(1999)
    # output_image = Laplacian_blending(H_img1.copy(), output_img.copy())

    # cv2.imshow('blend', output_image)
    # 待融合ROI[start:start+width, 0: img0.shape[1]]
    # for x in H_img1[0:img0.shape[1],int(start):int(start)+int(width)]:
    #    for i in x:

    #cv2.imshow(u'Left Img', tmp_r)
    #cv2.imshow(u'Right Img', tmp_l)

    # result = blender.multi_band_blending(tmp_l, tmp_r, overlap_w)
    # cv2.imshow('output_stage_1', result)
    '''
    start to blend
    '''

    return output_img
def computeMatrix():
    """Computes the homography on the image using the selected points and
    transforms the image

    Returns:
    - the 3x3 transformation matrix
    """
    # grab reference to the global variables
    global refPts
    global image

    # points should be in order of bottom right, top right, top left, bottom left
    # x point first, then y point
    quadrilateral = np.array(refPts, dtype=np.float32)
    br, tr, tl, bl = quadrilateral

    # width of rectangle to transform to is max distance between either top left
    # and top right coordinates, or bottom left and bottom right coordinates
    widthA = np.sqrt(((br[0] - bl[0])**2) + ((br[1] - bl[1])**2))
    widthB = np.sqrt(((tr[0] - tl[0])**2) + ((tr[1] - tl[1])**2))
    maxWidth = max(int(widthA), int(widthB))

    # height of rectangle to transform to is max distance between either top left
    # and bottom left, or top right and bottom right
    heightA = np.sqrt(((tr[0] - br[0])**2) + ((tr[1] - br[1])**2))
    heightB = np.sqrt(((tl[0] - bl[0])**2) + ((tl[1] - bl[1])**2))
    maxHeight = max(int(heightA), int(heightB))

    # rectangle to transform to, the corresponding points should be in the same
    # order as the passed in points
    dst = np.array([[maxWidth - 1, maxHeight - 1], [maxWidth - 1, 0], [0, 0],
                    [0, maxHeight - 1]],
                   dtype=np.float32)

    # Compute the perspective transform matrix
    homography = cv2.getPerspectiveTransform(quadrilateral, dst)

    # Find where the corners go after the transformation
    img_height, img_width = image.shape[:2]
    corners = np.array([[0, 0], [0, img_height - 1],
                        [img_width - 1, img_height - 1], [img_width - 1, 0]],
                       dtype=np.float32)

    # transformed corners
    t_corners = cv2.perspectiveTransform(np.float32([corners]), homography)[0]

    # Find the bounding rectangle around the warped image
    bx, by, bwidth, bheight = cv2.boundingRect(t_corners)

    # Compute new homography that makes the bounding box around the warped image
    # start at (0, 0)
    pure_translation = np.array([[1, 0, -bx], [0, 1, -by], [0, 0, 1]])

    # if A and B are homographies, A*B represents the homography that applies
    # B first, then A
    M = np.matmul(pure_translation, homography)

    # Get the warped image
    warped = cv2.warpPerspective(image, M, (bwidth, bheight))
    # Resize the warped image to be same height as original so we can display
    # them side by side
    warped = imutils.resize(warped, height=img_height)

    return M, warped
def orientation_detect(img, contours, H, rho=8.0, ntheta=512):

    # ignore this, just deal with edge-detected text

    pts = np.vstack(tuple(contours))
    
    shape, TH = warp_containing_points(img, pts, H, shape_only=True)

    text_edges = np.zeros(shape, dtype=np.uint8)

    for contour in contours:
        contour = cv2.perspectiveTransform(contour.astype(np.float32), TH)
        cv2.drawContours(text_edges, [contour.astype(int)], 0, (255,255,255))
        
    debug_show('edges', text_edges)

    # generate a linspace of thetas
    thetas = np.linspace(-0.5*np.pi, 0.5*np.pi, ntheta, endpoint=False)

    # rho is pixels per r bin in polar (theta, r) histogram
    # irho is bins per pixel
    irho = 1.0/rho

    # get height and width
    h, w = text_edges.shape

    # maximum bin index is given by hypotenuse of (w, h) divided by pixels per bin
    bin_max = int(np.ceil(np.hypot(w, h)*irho))

    # initialize zeroed histogram height bin_max and width num theta
    hist = np.zeros((bin_max, ntheta))

    # let u and v be x and y coordinates (respectively) of non-zero
    # pixels in edge map
    v, u = np.mgrid[0:h, 0:w]
    v = v[text_edges.view(bool)]
    u = u[text_edges.view(bool)]

    # get center coordinates
    u0 = w*0.5
    v0 = h*0.5

    # for each i and theta = thetas[i]
    for i, theta in enumerate(thetas):

        # for each nonzero edge pixel, compute bin in r direction from
        # pixel location and cos/sin of theta
        bin_idx =  ( (-(u-u0)*np.sin(theta) # x term
                      + (v-v0)*np.cos(theta))*irho # y term, both
                                                   # divided by pixels
                                                   # per bin
                     + 0.5*bin_max ) # offset for center pixel
        
        assert( bin_idx.min() >= 0 and bin_idx.max() < bin_max )

        # 0.5 is for correct rounding here
        #
        # e.g. np.bincount([1, 1, 0, 3]) = [1, 2, 0, 1]
        # returns count of each integer in the array

        bc = np.bincount((bin_idx + 0.5).astype(int))

        # push this into the histogram
        hist[:len(bc),i] = bc

    # number of zero pixels in each column
    num_zero = (hist == 0).sum(axis=0)

    # find the maximum number of zero pixels
    best_theta_idx = num_zero.argmax()

    # actual detected theta - could just return this now
    theta = thetas[best_theta_idx]

    # compose with previous homography 
    RH = np.dot(rotation(-theta), H)
    
    if 1: # just debug visualization

        debug_hist = (255*hist/hist.max()).astype('uint8')
        debug_hist = cv2.cvtColor(debug_hist, cv2.COLOR_GRAY2RGB)

        cv2.line(debug_hist,
                 (best_theta_idx, 0),
                 (best_theta_idx, bin_max), (255,0,0),
                 1, cv2.LINE_AA)
        
        debug_show('histogram', debug_hist)

        p0 = np.array((u0, v0))
        t = np.array((np.cos(theta), np.sin(theta)))

        warped = cv2.warpPerspective(img, TH, (shape[1], shape[0]),
                                     borderMode=cv2.BORDER_REPLICATE)

        
        debug_show('prerotate_noline', warped)

        cv2.line(warped,
                 tuple(map(int, p0 - rho*bin_max*t)),
                 tuple(map(int, p0 + rho*bin_max*t)),
                 (255, 0, 0),
                 6, cv2.LINE_AA)

        debug_show('prerotate', warped)

        warped, _ = warp_containing_points(img, pts, RH)
        debug_show('preskew', warped)
        
    return RH
def get_template(img2):
    global ROI, MIN_MATCH_COUNT, font, pts, kp1, des1, flann

    # Find the keypoints and descriptors with SIFT
    kp2, des2 = sift.detectAndCompute(img2, None)

    print("Keypoints in 1st Image: " + str(len(kp1)))
    print("Keypoints in 2nd Image: " + str(len(kp2)))

    matches = flann.knnMatch(des1, des2, k=2)

    # Store all good matches as per Lowe's ratio test
    good = []
    for m, n in matches:
        if m.distance < 0.7 * n.distance:
            good.append(m)

    number_keypoints = 0
    if (len(kp1) <= len(kp2)):
        number_keypoints = len(kp1)
    else:
        number_keypoints = len(kp2)

    number_goodpoints = len(good)
    print("Good matches found: " + str(number_goodpoints))
    similariy_percentage = float(number_goodpoints) / number_keypoints * 100
    print(similariy_percentage)

    res = 0

    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)
        matchesMask = mask.ravel().tolist()

        dst = cv2.perspectiveTransform(pts, M)

        x = []
        y = []
        (rows, columns) = (dst.shape[0], dst.shape[1])
        for i in range(rows):
            array = dst[i][0]
            x.append(array[0])
            y.append(array[1])

        if (initROI == True):
            for i in range(rows):
                res = res + 1 if (compareCoor(ROI[1], x[i], y[i])
                                  == True) else res + 0
            # if(res == 4):
            #     print("Label is correct")
            #     cv2.putText(img2, 'Label is pasted correct', (0, 50), font, 1, (0,255,0), 2)
            #     cv2.putText(img2, 'Input sample: {:.0f} %'.format(similariy_percentage), (0, 100), font, 1, (0,255,0), 2)
            #     count += 1
            # else:
            #     print("Label is pasted wrong")
            #     cv2.putText(img2, 'Label is pasted wrong', (0, 50), font, 1, (0,255,0), 2)
            #     cv2.putText(img2, 'Input sample: {:.0f} %'.format(similariy_percentage), (0, 100), font, 1, (0,255,0), 2)
        else:
            print("There is no ROI reference to check")
            cv2.putText(img2, 'No ROI found', (0, 50), font, 1, (0, 255, 0), 2)

        img2 = cv2.polylines(img2, [np.int32(dst)], True, (0, 255, 0), 3,
                             cv2.LINE_AA)
    else:
        res = -1
        cv2.putText(img2, 'No label found', (0, 50), font, 1, (0, 255, 0), 2)
        print("Not enough matches are found - %d/%d" %
              (len(good), MIN_MATCH_COUNT))
        matchesMask = None
    return res