Ejemplo n.º 1
0
    def process_image(self, msg):
        try:
            cvim = self.bridge.imgmsg_to_cv(msg, 'bgr8')
        except CvBridgeError as err:
            rospy.logerr(e)
            return

        if self.boxes: cv.PolyLine(cvim, self.boxes, True, (0, 0, 255))
        if self.selected_obj_id:
            cv.FillPoly(cvim, [self.boxes[self.selected_obj_id]],
                        (0, 0, 255, 0.5))

        # display object names
        if self.object_centers_msg:
            for center, color, category in zip(
                    self.object_centers_msg.centers,
                    self.object_centers_msg.color_labels,
                    self.object_centers_msg.category_labels):
                cv.PutText(cvim, color + ' ' + category,
                           (center.pixel.x, center.pixel.y), self.font,
                           (0, 0, 255))

        # display trajector
        if self.trajector_location:
            cv.Circle(cvim,
                      self.trajector_location,
                      3, (255, 0, 0),
                      thickness=2,
                      lineType=cv.CV_AA,
                      shift=0)
            cv.PutText(cvim, 'trajector', self.trajector_location, self.font,
                       (255, 0, 0))

        # display selected landmark
        if self.meaning:
            lmk = self.meaning.args[0]

            p_arr = self.lmk_geo_to_img_geo(lmk)

            if isinstance(lmk.representation, PointRepresentation):
                cv.Circle(cvim,
                          tuple(map(int, p_arr[0])),
                          3, (0, 255, 0),
                          thickness=2,
                          lineType=cv.CV_AA,
                          shift=0)
            else:
                pl = [[tuple(map(int, l)) for l in p_arr]]
                cv.PolyLine(cvim, pl, True, (0, 255, 0), thickness=3)

        cv.ShowImage('img', cvim)
        cv.WaitKey(10)
Ejemplo n.º 2
0
  def publishBoxData(self):
    #Extract the characteristics of the bounding box.
    xl = self.br[0]
    xr = xl + self.br[2]
    yt = self.br[1]
    yb = yt + self.br[3]

    #Form the data to send
    left    = float(xl)/self.size[0]
    top     = float(yt)/self.size[1]
    right   = float(xr)/self.size[0]
    bottom  = float(yb)/self.size[1]
    centerX = left + (right - left)/2
    centerY = bottom + (top - bottom)/2
    area    = 1.0*(xr-xl)*(yb-yt)/(self.size[0]*self.size[1])
    
    #Draw a contour around the bounding box.
    cv.PolyLine(self.image,[[(xl,yt),(xl,yb),(xr,yb),(xr,yt)]],10, cv.RGB(0, 0, 255))

    #Publish the bounding box.
    #Format is: "CenterX (in percent of box width) CenterY (in percent of box height)
    #            Area (in percent of box area) LeftEdge (in percent of box width)
    #            TopEdge (in percent of box height) RightEdge (in percent of box width)
    #            BottomEdge (in percent of box height)"

    self.publisher.publish("%f %f %f %f %f %f %f" % (centerX, centerY, area, left, top, right, bottom))
Ejemplo n.º 3
0
def draw_subdiv_facet( img, edge ):

    t = edge;
    count = 0;

    # count number of edges in facet
    while count == 0 or t != edge:
        count+=1
        t = cv.Subdiv2DGetEdge( t, cv.CV_NEXT_AROUND_LEFT );

    buf = []

    # gather points
    t = edge;
    for i in range(count):
        assert t>4
        pt = cv.Subdiv2DEdgeOrg( t );
        if not pt: 
            break;
        buf.append( ( cv.Round(pt.pt[0]), cv.Round(pt.pt[1]) ) );
        t = cv.Subdiv2DGetEdge( t, cv.CV_NEXT_AROUND_LEFT );

    if( len(buf)==count ):
        pt = cv.Subdiv2DEdgeDst( cv.Subdiv2DRotateEdge( edge, 1 ));
        cv.FillConvexPoly( img, buf, cv.RGB(random.randrange(256),random.randrange(256),random.randrange(256)), cv.CV_AA, 0 );
        cv.PolyLine( img, [buf], 1, cv.RGB(0,0,0), 1, cv.CV_AA, 0);
        draw_subdiv_point( img, pt.pt, cv.RGB(0,0,0));
Ejemplo n.º 4
0
	def draw_fft(self, frame, fft_data, min_bpm, max_bpm):
		w = frame.width
		h = int(frame.height * Annotator.FFT_HEIGHT)
		x = 0
		y = frame.height
		
		max_magnitude = max(d[1][0] for d in fft_data)
		
		def get_position(i):
			point_x = int(w * (float(fft_data[i][0] - min_bpm) / float(max_bpm - min_bpm)))
			point_y = int(y - ((h * fft_data[i][1][0]) / max_magnitude))
			return point_x, point_y
		
		line = [get_position(i) for i in range(len(fft_data))]
		
		cv.PolyLine(frame, [line], False, self.get_colour()[0], 3)
		
		# Label the largest bin
		max_bin = max(range(len(fft_data)), key=(lambda i: fft_data[i][1][0]))
		
		x,y = get_position(max_bin)
		c = self.get_colour()
		text = "%0.1f"%fft_data[max_bin][0]
		
		cv.PutText(frame, text, (x,y), self.small_font_outline, c[1])
		cv.PutText(frame, text, (x,y), self.small_font, c[0])
		
		# Pulse ring
		r = Annotator.SMALL_PULSE_SIZE
		phase = int(((fft_data[max_bin][1][1] % (2*numpy.pi)) / numpy.pi) * 180)
		cv.Ellipse(frame, (int(x-(r*1.5)),int(y-r)), (int(r),int(r)), 0, 90, 90-phase, c[1], Annotator.THIN+Annotator.BORDER)
		cv.Ellipse(frame, (int(x-(r*1.5)),int(y-r)), (int(r),int(r)), 0, 90, 90-phase, c[0], Annotator.THIN)
Ejemplo n.º 5
0
def dewarp(image, window, clicked_corners):
    debug = cv.CloneImage(image)

    # draw red line around edges for debug purposes
    cv.PolyLine(debug, [[
        clicked_corners[0], clicked_corners[1], clicked_corners[3],
        clicked_corners[2]
    ]], True, cv.RGB(0, 255, 0), 7)

    cv.ShowImage(window, debug)
    cv.WaitKey()

    # Assemble a rotated rectangle out of that info
    #rot_box = cv.MinAreaRect2(corners)
    enc_box = cv.BoundingRect(clicked_corners)
    new_corners = [(0, 0), (enc_box[2] - 1, 0), (0, enc_box[3] - 1),
                   (enc_box[2] - 1, enc_box[3] - 1)]

    warp_mat = cv.CreateMat(3, 3, cv.CV_32FC1)
    cv.GetPerspectiveTransform(clicked_corners, new_corners, warp_mat)

    rotated = cv.CloneImage(image)
    cv.WarpPerspective(image, rotated, warp_mat)

    cv.ShowImage(window, rotated)
    cv.WaitKey(10)

    return rotated
Ejemplo n.º 6
0
    def lineScan(self, image, source=None):
        """ Performs contour detection on a single channel image.
            Returns a set of 2d points containing the outer left line for the
            detected contours.
        """
        storage = cv.CreateMemStorage()
        contours = cv.FindContours(image,
                                   storage,
                                   mode=cv.CV_RETR_EXTERNAL,
                                   method=cv.CV_CHAIN_APPROX_NONE,
                                   offset=(0, 0))
        points = []

        if contours:
            cv.DrawContours(source, contours, (0, 0, 0), (0, 0, 0), 7, -1)

            while contours:
                y_max = max([y for _, y in contours])
                seq = [(x, y) for x, y in contours]
                i = 0

                # extract only the left side of the polygon
                for i in range(0, len(seq) - 1):
                    if seq[i][1] == y_max:
                        break

                seq = seq[:i]

                if source:  # draws the detected polygon line as feedback
                    cv.PolyLine(source, [seq], False, (0, 255, 0), 1, 8, 0)

                points.extend(seq)
                contours = contours.h_next()

        return points
Ejemplo n.º 7
0
def get_finger_tips(contours, img):
    finger_tips = []
    for ct in contours:
        if not ct: break

        x, y, r, b = find_max_rectangle(ct)
        # adjust ratio to at least 1/2
        ratio = abs(float(y - b) / (x - r))
        if ratio > 2:
            b = y + abs(x - r) * 2
        cv.Rectangle(img, (x, y), (r, b), color.RED)
        # draw center
        rotate_center = ((x + r) / 2, y + 100)
        cv.Circle(img, rotate_center, 5, (255, 0, 255, 0), cv.CV_FILLED,
                  cv.CV_AA, 0)

        cv.DrawContours(img, ct, color.RED, color.GREEN, 1, thickness=3)
        # Draw the convex hull as a closed polyline in green
        hull = find_convex_hull(ct)
        if (hull != None):
            cv.PolyLine(img, [hull], 1, cv.RGB(0, 255, 0), 3, cv.CV_AA)
            tip = find_finger_tip(hull, img)
            if tip != (-1, -1):
                finger_tips.append(tip)
    return finger_tips
Ejemplo n.º 8
0
def main():
    img = cv.LoadImage("latex/Pictures/IMG_7324.CR2.jpg")
    img = normalize_rgb(img, aggressive=0.005)
    mask, seqs, time = get_mask_with_contour(img, ret_cont=True, ret_img=True, with_init_mask=False, time_took=True)
    boxes, min_rects = get_skin_rectangles(seqs)
    draw_boxes(boxes, img)
    center = [(c[0],c[1]) for c,_,_ in min_rects]
    verticies = []
    for x,y,w,h in boxes:
        verticies+=[(x,y), (x+w,y),(x,y+h),(x+w,y+h)]

#    verticies = [(x+w/2, y+h/2) for x,y,w,h in boxes]

    polys = map(cv.BoxPoints, min_rects)
    cv.PolyLine(img, polys, True, cv.RGB(50,50,255), 2)

    sample_count = len(verticies)
    samples = cv.CreateMat(sample_count, 1, cv.CV_32FC2)
    clusters = cv.CreateMat(sample_count, 1, cv.CV_32SC1)
    [cv.Set1D(samples, i, verticies[i]) for i in range(sample_count)]
    cv.KMeans2(samples, 3, clusters,
                   (cv.CV_TERMCRIT_EPS + cv.CV_TERMCRIT_ITER, 10, 1.0))
    color = [cv.RGB(255,10,10),
             cv.RGB(255,255,10),
             cv.RGB(10,255,255),
             cv.RGB(255,10,255)]
    for i, xy in enumerate(verticies):
        cv.Circle(img, xy, 5, color[int(clusters[i,0])], thickness=-1)

#    np_centers = np.asarray(verticies)
#    result = cv.kmeans(verticies, 2, 0, 5, cv.CV_TERMCRIT_ITER)

    show_image(img)
Ejemplo n.º 9
0
def draw_common(points):
    success, center, radius = cv.MinEnclosingCircle(points)
    if success:
        cv.Circle(img, roundxy(center), cv.Round(radius),
                  cv.CV_RGB(255, 255, 0), 1, cv.CV_AA, 0)

    box = cv.MinAreaRect2(points)
    box_vtx = [roundxy(p) for p in cv.BoxPoints(box)]
    cv.PolyLine(img, [box_vtx], 1, cv.CV_RGB(0, 255, 255), 1, cv.CV_AA)
Ejemplo n.º 10
0
def mouse_section(D):
    """Displays a rectangle defined by dragging the mouse."""

    if D.mouse_down:
        x0 = D.down_coord[0]
        y0 = D.down_coord[1]
        x1 = D.up_coord[0]
        y1 = D.up_coord[1]
        cv.PolyLine(D.image, [[(x0, y0), (x0, y1), (x1, y1), (x1, y0)]], 1,
                    cv.RGB(0, 255, 0))
Ejemplo n.º 11
0
def PolyLine(img, polys, is_closed, color, text=None, scale_f=1):
    if not DEBUG: return
    if scale_f != 1:
        polys[0] = map(lambda p: scale(p, scale_f), polys[0])
    polys[0] = [(int(p[0]), int(p[1])) for p in polys[0]]
    cv.PolyLine(img, polys, is_closed, color)
    if text is not None:
        polys = polys[0]
        x, y = reduce(lambda (x, y), (w, z): (x + w, y + z), polys, (0, 0))
        cv.PutText(img, text, (x / len(polys), y / len(polys)), font,
                   (0, 255, 255))
Ejemplo n.º 12
0
def draw_squares( color_img, squares ):
    """
    Squares is py list containing 4-pt numpy arrays. Step through the list
    and draw a polygon for each 4-group
    """
    color, othercolor = RED, GREEN
    for square in squares:
        cv.PolyLine(color_img, [square], True, color, 3, cv.CV_AA, 0)
        color, othercolor = othercolor, color

    cv.ShowImage(WNDNAME, color_img)
Ejemplo n.º 13
0
 def mouse_callback(self,event,u,v,flags,params):
     if event==cv.CV_EVENT_LBUTTONDOWN:
         self.first_corner = (u,v)
         self.drawing = True
     elif event==cv.CV_EVENT_LBUTTONUP:
         self.second_corner = (u,v)
         self.drawing = False
     elif event==cv.CV_EVENT_MOUSEMOVE and self.drawing:
         image2 = cv.CreateMat(self.image.height,self.image.width,cv.CV_8UC3)
         cv.Copy(self.image,image2)
         (x,y) = self.first_corner
         cv.PolyLine(image2,[[(x,y),(x,v),(u,v),(u,y)]],1,(255,255,255))
         cv.ShowImage(self.window_name,image2)
Ejemplo n.º 14
0
def find_biggest_region():
    """ finds all the contours in threshed image, finds the largest of those,
        and then marks in in the main image
    """
    # get D so that we can change values in it
    global D

    cv.Copy(D.threshed_image, D.copy)  # copy threshed image

    # this is OpenCV's call to find all of the contours:
    contours = cv.FindContours(D.copy, D.storage, cv.CV_RETR_EXTERNAL, \
                                   cv.CV_CHAIN_APPROX_SIMPLE)

    # Next we want to find the *largest* contour
    if len(contours) > 0:
        biggest = contours
        biggestArea = cv.ContourArea(contours)
        while contours != None:
            nextArea = cv.ContourArea(contours)
            if biggestArea < nextArea:
                biggest = contours
                biggestArea = nextArea
            contours = contours.h_next()

        # Use OpenCV to get a bounding rectangle for the largest contour
        br = cv.BoundingRect(biggest, update=0)

        #print "in find_regions, br is", br

        # Example of drawing a red box
        # Variables: ulx ~ upper left x, lry ~ lower right y, etc.
        ulx = br[0]
        lrx = br[0] + br[2]
        uly = br[1]
        lry = br[1] + br[3]
        cv.PolyLine(D.image, [[(ulx, uly), (lrx, uly), (lrx, lry),
                               (ulx, lry)]], 1, cv.RGB(255, 0, 0))

        # Example of drawing a yellow circle
        # Variables: cenx, ceny
        cenx = (ulx + lrx) / 2
        ceny = (uly + lry) / 2
        cv.Circle(D.image, (cenx, ceny),
                  8,
                  cv.RGB(255, 255, 0),
                  thickness=1,
                  lineType=8,
                  shift=0)
Ejemplo n.º 15
0
def motion_bbox(output, motion):
    #global muestra, prom
    global bbox_list
    #INICIO = time.time()
    contour = cv.FindContours(motion, mem_storage, cv.CV_RETR_CCOMP,
                              cv.CV_CHAIN_APPROX_SIMPLE)
    bbox_list = []  #lista para almacenar los bounding box de las manchas
    average_box_area = 0  #variable para obtener el area en promedio de las bounding box
    while contour:  #recorrido de los contornos/manchas
        bbox = cv.BoundingRect(
            list(contour))  #obtencion del bounding box del contorno actual
        pt1 = (bbox[0], bbox[1])  #punto 1 del bounding box
        pt2 = (bbox[0] + bbox[2], bbox[1] + bbox[3])  #punto 2 del bounding box
        w, h = abs(pt1[0] - pt2[0]), abs(
            pt1[1] - pt2[1])  #ancho y largo del bounding box
        #obtencion de puntos del contorno para crear un wire-frame
        polygon_points = cv.ApproxPoly(list(contour), mem_storage,
                                       cv.CV_POLY_APPROX_DP)
        #mostrar o las manchas de movimiento
        if SHOW_MOVEMENT_AREA:
            cv.FillPoly(output, [
                list(polygon_points),
            ], cv.CV_RGB(255, 255, 255), 0, 0)
        #mostrar o no los contornos de las manchas de movimiento
        if SHOW_MOVEMENT_CONTOUR and w * h > AREA * MIN_PERCENT:
            cv.PolyLine(output, [
                polygon_points,
            ], 0, cv.CV_RGB(255, 255, 255), 1, 0, 0)
        average_box_area += w * h  #acumulacion de totales de areas
        bbox_list.append((pt1, pt2))  #lista con todos los bounding box
        contour = contour.h_next()  #lectura del siguiente contorno, si hay
    if len(bbox_list) > 0:  #si hubo movimiento
        average_box_area = average_box_area / float(
            len(bbox_list))  #area promedio de bounding box
        new_bbox_list = [
        ]  #nueva lista de bounding box, eliminando los menores al area promedio
        for i in range(len(bbox_list)):  #recorrido de los bounding box
            pt1, pt2 = bbox_list[i]  #separacion en dos puntos del bounding box
            w, h = abs(pt1[0] - pt2[0]), abs(
                pt1[1] - pt2[1])  #obtencion del ancho y largo
            if w * h >= average_box_area and w * h > AREA * MIN_PERCENT:  #comparacion del area del bounding box con el promedio
                new_bbox_list.append(
                    (pt1,
                     pt2))  #si es mayor o igual, se queda en la nueva lista
    bbox_list = get_collided_bboxes(
        new_bbox_list
    )  #combinacion de varios bounding box en uno si estan en contacto
Ejemplo n.º 16
0
def drawSquares(img, squares):
    cpy = cv.CloneImage(img)
    # read 4 sequence elements at a time (all vertices of a square)
    i = 0
    while i < squares.total:
        pt = []
        # read 4 vertices
        pt.append(squares[i])
        pt.append(squares[i + 1])
        pt.append(squares[i + 2])
        pt.append(squares[i + 3])

        # draw the square as a closed polyline
        cv.PolyLine(cpy, [pt], 1, cv.CV_RGB(0, 255, 0), 3, cv.CV_AA, 0)
        i += 4

    # show the resultant image
    cv.ShowImage(wndname, cpy)
Ejemplo n.º 17
0
    def get_candidates(self, m_d):
        '''
        Get candidates for this corner from new image
        @param m_d: marker_detector
        '''
        # if this corner is wider then MAX_CORNER_ANGLE, we probably won't
        # find it anyway. Instead lets find narrow corners and calculate its
        # position
        if self.angle > MAX_CORNER_ANGLE: return []
        cr = self.get_rectangle(m_d)
        cr = correct_rectangle(cr, m_d.size)
        if cr is None: return []
        m_d.set_ROI(cr)
        tmp_img = m_d.tmp_img
        gray_img = m_d.gray_img
        bw_img = m_d.bw_img
        canny = m_d.canny_img
        cv.Copy(gray_img, tmp_img)
        cv.Threshold(gray_img, bw_img, 125, 255, cv.CV_THRESH_OTSU)
        if self.black_inside > 0:
            cv.Not(bw_img, bw_img)
        cv.Canny(gray_img, canny, 300, 500)
        cv.Or(bw_img, canny, bw_img)
        tmpim = m_d.canny_img
        cv.Copy(bw_img, tmpim)
        cv.Set2D(tmpim, 1, 1, 255)
        conts = cv.FindContours(tmpim, cv.CreateMemStorage(),
                                cv.CV_RETR_EXTERNAL)
        cv.Zero(tmpim)
        m_d.set_ROI()
        cv.SetImageROI(tmpim, cr)
        result = []
        while conts:
            aconts = cv.ApproxPoly(conts, cv.CreateMemStorage(),
                                   cv.CV_POLY_APPROX_DP, 2)
            nconts = list(aconts)
            cv.PolyLine(tmpim, [nconts], True, (255, 255, 255))
            self._append_candidates_from_conts(cr, result, nconts, m_d)
            conts = conts.h_next()


#        print result
#        db.show([tmpim,m_d.draw_img], 'tmpim', 0, 0, 0)
        return result
Ejemplo n.º 18
0
    def getAnnotatedImage(self,
                          showRects=True,
                          showContours=False,
                          showConvexHulls=False,
                          showFlow=False):
        '''
        @return: the annotation image with selected objects drawn upon it. showFlow will
        only work if the BG subtraction method was MCFD.
        @note: You must call detect() prior to getAnnotatedImage() to see updated results.
        '''
        rects = self.getRects()
        outImg = self._annotateImg.copy(
        )  #deep copy, so can freely modify the copy
        if outImg == None: return None

        #draw optical flow information in white
        if showFlow and (self._method == pv.BG_SUBTRACT_MCFD):
            flow = self._bgSubtract.getOpticalFlow()
            flow.annotateFrame(outImg)

        if showContours or showConvexHulls:
            cvimg = outImg.asOpenCV()

        #draw contours in green
        if showContours:
            cv.DrawContours(cvimg, self._contours, cv.RGB(0, 255, 0),
                            cv.RGB(255, 0, 0), 2)

        #draw hulls in cyan
        if showConvexHulls:
            cv.PolyLine(cvimg, self._convexHulls, True, cv.RGB(0, 255, 255))

        #draw bounding box in yellow
        if showRects:
            for r in rects:
                outImg.annotateRect(r, "yellow")

        return outImg
Ejemplo n.º 19
0


if __name__ == '__main__':
    img = cv.CreateImage((100, 100), 8, 1)
    a = (50, -10)
    b = (85, 50)
    c = (50, 90)
    d = (5, 50)
    cv.FillConvexPoly(img, [a, b, c, d], (255, 255, 255))
    temp = 'temp'
    cv.NamedWindow(temp)

    oa, ob, oc, od = (48, -8), (80, 50), (48, 88), (0, 50)
    points = [oa, ob, oc, od]
    corners = [Corner(points, 0), Corner(points, 1), Corner(points, 2), Corner(points, 3)]
    CP = CornerPredictor(corners, 50, img)

    cv.PolyLine(img, [[oa, ob, oc, od]], 1, (150, 100, 100))

    dimg = cv.CreateImage((200, 200), 8, 1)
    cv.PyrUp(img, dimg)
    cv.ShowImage(temp, dimg)
    cv.WaitKey(10000)






Ejemplo n.º 20
0
    def show(self):
        """ Process and show the current frame """
        source = cv.LoadImage(self.files[self.index])
        width, height = cv.GetSize(source)

        center = (width / 2) + self.offset

        cv.Line(source, (center, 0), (center, height), (0, 255, 0), 1)

        if self.roi:
            x, y, a, b = self.roi

            print self.roi

            width, height = ((a - x), (b - y))
            mask = cv.CreateImage((width, height), cv.IPL_DEPTH_8U, 1)

            cv.SetImageROI(source, (x, y, width, height))
            cv.Split(source, None, None, mask, None)

            gray = cv.CloneImage(mask)

            cv.InRangeS(mask, self.thresholdMin, self.thresholdMax, mask)
            cv.And(mask, gray, gray)

            line = []
            points = []

            for i in range(0, height - 1):
                row = cv.GetRow(gray, i)

                minVal, minLoc, maxLoc, maxVal = cv.MinMaxLoc(row)

                y = i
                x = maxVal[0]
                point = (0, 0, height - i)

                if x > 0:
                    line.append((x, y))

                    s = x / sin(radians(self.camAngle))
                    x = s * cos(self.angles[self.index])
                    z = height - y
                    y = s * sin(self.angles[self.index])

                    point = (round(x, 2), round(y, 2), z)

                points.append(point)

            cv.PolyLine(source, [line], False, (255, 0, 0), 2, 8)
            cv.ResetImageROI(source)
            x, y, a, b = self.roi
            cv.Rectangle(source, (int(x), int(y)), (int(a), int(b)),
                         (255.0, 255, 255, 0))

        if self.roi:
            x, y, a, b = self.roi

            width, height = ((a - x), (b - y))
            mask = cv.CreateImage((width, height), cv.IPL_DEPTH_8U, 1)

            cv.SetImageROI(
                source, (x - width, y, width, height))  # moves roi to the left
            cv.Split(source, None, None, mask, None)

            gray = cv.CloneImage(mask)

            cv.InRangeS(mask, self.thresholdMin, self.thresholdMax, mask)
            cv.And(mask, gray, gray)

            line = []
            points2 = []

            for i in range(0, height - 1):
                row = cv.GetRow(gray, i)

                minVal, minLoc, maxLoc, maxVal = cv.MinMaxLoc(row)

                y = i
                x = maxVal[0]
                point = (0, 0, height - i)

                if x > 0:
                    line.append((x, y))

                    x = width - x
                    # left to the x-axis

                    s = x / sin(radians(self.camAngle))

                    x = s * cos(self.angles[self.index])
                    z = height - y  # 500 higher then the other.
                    y = s * sin(self.angles[self.index])

                    a = radians(300)

                    nx = (cos(a) * x) - (sin(a) * y)
                    ny = (sin(a) * x) + (cos(a) * y)

                    point = (nx, ny, z)

                points2.append(point)

            cv.PolyLine(source, [line], False, (255, 0, 0), 2, 8)
            cv.ResetImageROI(source)
            x, y, a, b = self.roi
            cv.Rectangle(source, (int(x), int(y)), (int(a), int(b)),
                         (255.0, 255, 255, 0))

        if self.mode == 'mask':
            cv.ShowImage('preview', mask)
            return

        if self.mode == 'record' and self.roi:
            font = cv.InitFont(cv.CV_FONT_HERSHEY_SIMPLEX, 0.5, 0.5, 1)
            cv.PutText(source, "recording %d" % self.index, (20, 20), font,
                       (0, 0, 255))
            self.points.extend(points)
            self.points2.extend(points2)
            #self.colors.extend(colors);

        cv.ShowImage('preview', source)
Ejemplo n.º 21
0
    cv.Set(temp, cv.RGB(0, 0, 0))
    cv.WarpAffine(src, temp, map)
    cv.Or(temp, bg, bg)

cv.ShowImage("comp", bg)
scribble = cv.CloneMat(bg)

if 0:
    for i in range(10):
        df.find(bg)

for (sym, coords) in df.find(bg).items():
    print sym
    cv.PolyLine(scribble, [coords],
                1,
                cv.CV_RGB(255, 0, 0),
                1,
                lineType=cv.CV_AA)
    Xs = [x for (x, y) in coords]
    Ys = [y for (x, y) in coords]
    where = ((min(Xs) + max(Xs)) / 2, max(Ys) - 50)
    cv.PutText(scribble, sym, where, font, cv.RGB(0, 255, 0))

cv.ShowImage("results", scribble)
cv.WaitKey()

sys.exit(0)

capture = cv.CaptureFromCAM(0)
while True:
    img = cv.QueryFrame(capture)
Ejemplo n.º 22
0
 def draw_hull(self, im, rgb=(0, 255, 0)):
     cv.PolyLine(im, [self.hull], 1, cv.RGB(*rgb), 1, cv.CV_AA)
Ejemplo n.º 23
0
def find_biggest_region(D):
    """ finds all the contours in threshed image, finds the largest of those,
        and then marks in in the main image
    """

    # Create a copy image of thresholds then find contours on that image
    storage = cv.CreateMemStorage(0)  # Create memory storage for contours
    copy = cv.CreateImage(D.size, 8, 1)
    cv.Copy(D.threshed_image, copy)  # copy threshed image

    # this is OpenCV's call to find all of the contours:
    contours = cv.FindContours(copy, storage, cv.CV_RETR_EXTERNAL, \
                                   cv.CV_CHAIN_APPROX_SIMPLE)

    # Next we want to find the *largest* contour
    if len(contours) > 0:
        biggest = contours
        biggestArea = cv.ContourArea(contours)
        while contours != None:
            nextArea = cv.ContourArea(contours)
            if biggestArea < nextArea:
                biggest = contours
                biggestArea = nextArea
            contours = contours.h_next()

        # Use OpenCV to get a bounding rectangle for the largest contour
        br = cv.BoundingRect(biggest, update=0)

        #print "in find_regions, br is", br

        ulx, uly, width, height = br[0], br[1], br[2], br[3]

        D.br = (ulx, uly), (width, height)
        D.target_size = width * height

        # You will want to change these so that they draw a box
        # around the largest contour and a circle at its center:

        # Example of drawing a yellow box
        cv.PolyLine(D.image, [[(ulx,uly), (ulx+width,uly), (ulx+width,uly+height),\
       (ulx,uly+height)]], 1, cv.RGB(255, 255, 0))

        # Draw circle in the center of the target
        cv.Circle(D.image, (ulx+width/2,uly+height/2), 10, \
                      cv.RGB(255, 0, 0), thickness=1, lineType=8, shift=0)

        # Draw the contours in white with inner ones in green
        cv.DrawContours(D.image, biggest, cv.RGB(255, 255, 255), \
                            cv.RGB(0, 255, 0), 1, thickness=2, lineType=8, \
                            offset=(0,0))

        # Reset coordinates to keep track of where the center of the coutour is
        D.last_target_coord = D.target_coord
        D.target_coord = (ulx + width / 2, uly - height / 2)
        D.p1, D.p2, D.p3, D.p4 = (D.target_coord[0],D.target_coord[1] + height/2),\
            (D.target_coord[0],D.target_coord[1] + height/2), \
            (D.target_coord[0],D.target_coord[1] + height/2), \
            (D.target_coord[0],D.target_coord[1] + height/2)
    else:
        D.br = (0, 0), (0, 0)
        D.target_size = 0
        D.p1, D.p2, D.p3, D.p4 = (0, 0), (0, 0), (0, 0), (0, 0)
Ejemplo n.º 24
0
    def find_regions(self):

        #Create a copy image of thresholds then find contours on that image
        storage = cv.CreateMemStorage(0)
        storage1 = cv.CreateMemStorage(0)
        copy = cv.CreateImage(self.size, 8, 1)
        cv.Copy(self.threshold, copy)
        contours = cv.FindContours(copy, storage, cv.CV_RETR_EXTERNAL,\
                                   cv.CV_CHAIN_APPROX_SIMPLE)

        #Find the largest contour
        if len(contours) > 0:
            biggest = contours
            biggestArea = cv.ContourArea(contours)
            while contours != None:
                nextArea = cv.ContourArea(contours)
                if biggestArea < nextArea:
                    biggest = contours
                    biggestArea = nextArea
                contours = contours.h_next()

            #print biggest


#            after_biggest = biggest.h_next()
#            after_biggest = None

#Get a bounding rectangle for the largest contour
            br = cv.BoundingRect(biggest, update=0)

            #self.tree = cv.CreateContourTree(biggest, storage1, 0)

            #print self.contour_tree

            #Find the middle of it
            circle_x = br[0] + br[2] / 2
            circle_y = br[1] + br[3] / 2

            #Create a blob message and publish it.
            #            blob = Blob( br[0], br[1], br[2], br[3], circle_x, circle_y)
            #            self.publish(blob)

            #Find the coordinates for each corner of the box
            box_tl = (br[0], br[1])
            box_tr = (br[0] + br[2], br[1])
            box_bl = (br[0], br[1] + br[3])
            box_br = (br[0] + br[2], br[1] + br[3])

            #Draw the box
            cv.PolyLine(self.image,[[box_tl, box_bl, box_br, box_tr]],\
                        1, cv.RGB(255, 0, 0))

            #Draw the circle
            cv.Circle(self.image,(circle_x, circle_y), 10, cv.RGB(255, 0, 0),\
                      thickness=1, lineType=8, shift=0)

            #Draw the contours
            cv.DrawContours(self.image,
                            biggest,
                            cv.RGB(255, 255, 255),
                            cv.RGB(0, 255, 0),
                            1,
                            thickness=2,
                            lineType=8,
                            offset=(0, 0))
Ejemplo n.º 25
0
    def run(self):
        global centroid
        frame = cv.QueryFrame(self.capture)
        while not frame:
            cv.WaitKey(10)
            frame = cv.QueryFrame(self.capture)

        frame_size = cv.GetSize(frame)

        # Capture the first frame from webcam for image properties
        display_image = cv.QueryFrame(self.capture)

        while not display_image:
            cv.WaitKey(10)
            display_image = cv.QueryFrame(self.capture)

        # Greyscale image, thresholded to create the motion mask:
        grey_image = cv.CreateImage(cv.GetSize(frame), cv.IPL_DEPTH_8U, 1)

        # The RunningAvg() function requires a 32-bit or 64-bit image...
        running_average_image = cv.CreateImage(cv.GetSize(frame),
                                               cv.IPL_DEPTH_32F, 3)
        # ...but the AbsDiff() function requires matching image depths:
        running_average_in_display_color_depth = cv.CloneImage(display_image)

        # RAM used by FindContours():
        mem_storage = cv.CreateMemStorage(0)

        # The difference between the running average and the current frame:
        difference = cv.CloneImage(display_image)

        target_count = 1
        last_target_count = 1
        last_target_change_t = 0.0
        k_or_guess = 1
        codebook = []
        frame_count = 0
        last_frame_entity_list = []

        t0 = time.time()

        # For toggling display:
        image_list = ["camera", "difference", "threshold", "display", "faces"]
        image_index = 0  # Index into image_list

        # Prep for text drawing:
        text_font = cv.InitFont(cv.CV_FONT_HERSHEY_COMPLEX, .5, .5, 0.0, 1,
                                cv.CV_AA)
        text_coord = (5, 15)
        text_color = cv.CV_RGB(255, 255, 255)

        ###############################
        ### Face detection stuff
        haar_cascade = cv.Load('haarcascades/haarcascade_frontalface_alt.xml')

        # Set this to the max number of targets to look for (passed to k-means):
        max_targets = 3

        while True:

            # Capture frame from webcam
            camera_image = cv.QueryFrame(self.capture)

            while not camera_image:
                cv.WaitKey(10)
                camera_image = cv.QueryFrame(self.capture)

            frame_count += 1
            print 'frame_count = ', frame_count
            frame_t0 = time.time()

            # Create an image with interactive feedback:
            display_image = cv.CloneImage(camera_image)

            # Create a working "color image" to modify / blur
            color_image = cv.CloneImage(display_image)

            # Smooth to get rid of false positives
            cv.Smooth(color_image, color_image, cv.CV_GAUSSIAN, 19, 0)

            # Use the Running Average as the static background
            # a = 0.020 leaves artifacts lingering way too long.
            # a = 0.320 works well at 320x240, 15fps.  (1/a is roughly num frames.)
            cv.RunningAvg(color_image, running_average_image, 0.320, None)

            # Convert the scale of the moving average.
            cv.ConvertScale(running_average_image,
                            running_average_in_display_color_depth, 1.0, 0.0)

            # Subtract the current frame from the moving average.
            cv.AbsDiff(color_image, running_average_in_display_color_depth,
                       difference)

            # Convert the image to greyscale.
            cv.CvtColor(difference, grey_image, cv.CV_RGB2GRAY)

            # Threshold the image to a black and white motion mask:
            cv.Threshold(grey_image, grey_image, 2, 255, cv.CV_THRESH_BINARY)
            # Smooth and threshold again to eliminate "sparkles"
            cv.Smooth(grey_image, grey_image, cv.CV_GAUSSIAN, 19, 0)
            cv.Threshold(grey_image, grey_image, 240, 255, cv.CV_THRESH_BINARY)

            grey_image_as_array = numpy.asarray(cv.GetMat(grey_image))
            non_black_coords_array = numpy.where(grey_image_as_array > 3)
            # Convert from numpy.where()'s two separate lists to one list of (x, y) tuples:
            non_black_coords_array = zip(non_black_coords_array[1],
                                         non_black_coords_array[0])

            points = [
            ]  # Was using this to hold either pixel coords or polygon coords.
            bounding_box_list = []

            # Now calculate movements using the white pixels as "motion" data
            contour = cv.FindContours(grey_image, mem_storage,
                                      cv.CV_RETR_CCOMP,
                                      cv.CV_CHAIN_APPROX_SIMPLE)

            while contour:

                bounding_rect = cv.BoundingRect(list(contour))
                point1 = (bounding_rect[0], bounding_rect[1])
                point2 = (bounding_rect[0] + bounding_rect[2],
                          bounding_rect[1] + bounding_rect[3])

                bounding_box_list.append((point1, point2))
                polygon_points = cv.ApproxPoly(list(contour), mem_storage,
                                               cv.CV_POLY_APPROX_DP)

                # To track polygon points only (instead of every pixel):
                #points += list(polygon_points)

                # Draw the contours:
                ###cv.DrawContours(color_image, contour, cv.CV_RGB(255,0,0), cv.CV_RGB(0,255,0), levels, 3, 0, (0,0) )
                cv.FillPoly(grey_image, [
                    list(polygon_points),
                ], cv.CV_RGB(255, 255, 255), 0, 0)
                cv.PolyLine(display_image, [
                    polygon_points,
                ], 0, cv.CV_RGB(255, 255, 255), 1, 0, 0)
                #cv.Rectangle( display_image, point1, point2, cv.CV_RGB(120,120,120), 1)

                contour = contour.h_next()

            # Find the average size of the bbox (targets), then
            # remove any tiny bboxes (which are prolly just noise).
            # "Tiny" is defined as any box with 1/10th the area of the average box.
            # This reduces false positives on tiny "sparkles" noise.
            box_areas = []
            for box in bounding_box_list:
                box_width = box[right][0] - box[left][0]
                box_height = box[bottom][0] - box[top][0]
                box_areas.append(box_width * box_height)

                #cv.Rectangle( display_image, box[0], box[1], cv.CV_RGB(255,0,0), 1)

            average_box_area = 0.0
            if len(box_areas):
                average_box_area = float(sum(box_areas)) / len(box_areas)

            trimmed_box_list = []
            for box in bounding_box_list:
                box_width = box[right][0] - box[left][0]
                box_height = box[bottom][0] - box[top][0]

                # Only keep the box if it's not a tiny noise box:
                if (box_width * box_height) > average_box_area * 0.1:
                    trimmed_box_list.append(box)

            # Draw the trimmed box list:
            bounding_box_list = merge_collided_bboxes(trimmed_box_list)

            # Draw the merged box list:
            for box in bounding_box_list:
                cv.Rectangle(display_image, box[0], box[1],
                             cv.CV_RGB(0, 255, 0), 1)

            # Here are our estimate points to track, based on merged & trimmed boxes:
            estimated_target_count = len(bounding_box_list)

            # Don't allow target "jumps" from few to many or many to few.
            # Only change the number of targets up to one target per n seconds.
            # This fixes the "exploding number of targets" when something stops moving
            # and the motion erodes to disparate little puddles all over the place.

            if frame_t0 - last_target_change_t < .350:  # 1 change per 0.35 secs
                estimated_target_count = last_target_count
            else:
                if last_target_count - estimated_target_count > 1:
                    estimated_target_count = last_target_count - 1
                if estimated_target_count - last_target_count > 1:
                    estimated_target_count = last_target_count + 1
                last_target_change_t = frame_t0

            # Clip to the user-supplied maximum:
            estimated_target_count = min(estimated_target_count, max_targets)

            # The estimated_target_count at this point is the maximum number of targets
            # we want to look for.  If kmeans decides that one of our candidate
            # bboxes is not actually a target, we remove it from the target list below.

            # Using the numpy values directly (treating all pixels as points):
            points = non_black_coords_array
            center_points = []

            if len(points):

                # If we have all the "target_count" targets from last frame,
                # use the previously known targets (for greater accuracy).
                k_or_guess = max(estimated_target_count,
                                 1)  # Need at least one target to look for.
                if len(codebook) == estimated_target_count:
                    k_or_guess = codebook

                #points = vq.whiten(array( points ))  # Don't do this!  Ruins everything.
                codebook, distortion = vq.kmeans(array(points), k_or_guess)

                # Convert to tuples (and draw it to screen)
                for center_point in codebook:
                    center_point = (int(center_point[0]), int(center_point[1]))
                    center_points.append(center_point)
                    #cv.Circle(display_image, center_point, 10, cv.CV_RGB(255, 0, 0), 2)
                    #cv.Circle(display_image, center_point, 5, cv.CV_RGB(255, 0, 0), 3)

            # Now we have targets that are NOT computed from bboxes -- just
            # movement weights (according to kmeans).  If any two targets are
            # within the same "bbox count", average them into a single target.
            #
            # (Any kmeans targets not within a bbox are also kept.)

            trimmed_center_points = []
            removed_center_points = []

            for box in bounding_box_list:
                # Find the centers within this box:
                center_points_in_box = []

                for center_point in center_points:
                    if  center_point[0] < box[right][0] and center_point[0] > box[left][0] and \
                        center_point[1] < box[bottom][1] and center_point[1] > box[top][1] :

                        # This point is within the box.
                        center_points_in_box.append(center_point)

                # Now see if there are more than one.  If so, merge them.
                if len(center_points_in_box) > 1:
                    # Merge them:
                    x_list = y_list = []
                    for point in center_points_in_box:
                        x_list.append(point[0])
                        y_list.append(point[1])

                    average_x = int(float(sum(x_list)) / len(x_list))
                    average_y = int(float(sum(y_list)) / len(y_list))

                    trimmed_center_points.append((average_x, average_y))

                    # Record that they were removed:
                    removed_center_points += center_points_in_box

                if len(center_points_in_box) == 1:
                    trimmed_center_points.append(
                        center_points_in_box[0])  # Just use it.

            # If there are any center_points not within a bbox, just use them.
            # (It's probably a cluster comprised of a bunch of small bboxes.)
            for center_point in center_points:
                if (not center_point in trimmed_center_points) and (
                        not center_point in removed_center_points):
                    trimmed_center_points.append(center_point)

            # Determine if there are any new (or lost) targets:
            actual_target_count = len(trimmed_center_points)
            last_target_count = actual_target_count

            # Now build the list of physical entities (objects)
            this_frame_entity_list = []

            # An entity is list: [ name, color, last_time_seen, last_known_coords ]
            for target in trimmed_center_points:
                # Is this a target near a prior entity (same physical entity)?
                entity_found = False
                entity_distance_dict = {}

                for entity in last_frame_entity_list:

                    entity_coords = entity[3]
                    delta_x = entity_coords[0] - target[0]
                    delta_y = entity_coords[1] - target[1]

                    distance = sqrt(pow(delta_x, 2) + pow(delta_y, 2))
                    entity_distance_dict[distance] = entity

                # Did we find any non-claimed entities (nearest to furthest):
                distance_list = entity_distance_dict.keys()
                distance_list.sort()

                for distance in distance_list:
                    # Yes; see if we can claim the nearest one:
                    nearest_possible_entity = entity_distance_dict[distance]

                    # Don't consider entities that are already claimed:
                    if nearest_possible_entity in this_frame_entity_list:
                        #print "Target %s: Skipping the one iwth distance: %d at %s, C:%s" % (target, distance, nearest_possible_entity[3], nearest_possible_entity[1] )
                        continue

                    #print "Target %s: USING the one iwth distance: %d at %s, C:%s" % (target, distance, nearest_possible_entity[3] , nearest_possible_entity[1])
                    # Found the nearest entity to claim:
                    entity_found = True
                    nearest_possible_entity[
                        2] = frame_t0  # Update last_time_seen
                    nearest_possible_entity[
                        3] = target  # Update the new location
                    this_frame_entity_list.append(nearest_possible_entity)
                    #log_file.write( "%.3f MOVED %s %d %d\n" % ( frame_t0, nearest_possible_entity[0], nearest_possible_entity[3][0], nearest_possible_entity[3][1]  ) )
                    break

                if entity_found == False:
                    # It's a new entity.
                    color = (random.randint(0, 255), random.randint(0, 255),
                             random.randint(0, 255))
                    name = hashlib.md5(str(frame_t0) +
                                       str(color)).hexdigest()[:6]
                    last_time_seen = frame_t0

                    new_entity = [name, color, last_time_seen, target]
                    this_frame_entity_list.append(new_entity)
                    #log_file.write( "%.3f FOUND %s %d %d\n" % ( frame_t0, new_entity[0], new_entity[3][0], new_entity[3][1]  ) )

            # Now "delete" any not-found entities which have expired:
            entity_ttl = 1.0  # 1 sec.

            for entity in last_frame_entity_list:
                last_time_seen = entity[2]
                if frame_t0 - last_time_seen > entity_ttl:
                    # It's gone.
                    #log_file.write( "%.3f STOPD %s %d %d\n" % ( frame_t0, entity[0], entity[3][0], entity[3][1]  ) )
                    pass
                else:
                    # Save it for next time... not expired yet:
                    this_frame_entity_list.append(entity)

            # For next frame:
            last_frame_entity_list = this_frame_entity_list

            # Draw the found entities to screen:
            for entity in this_frame_entity_list:
                center_point = entity[3]
                c = entity[1]  # RGB color tuple
                cv.Circle(display_image, center_point, 20,
                          cv.CV_RGB(c[0], c[1], c[2]), 1)
                cv.Circle(display_image, center_point, 15,
                          cv.CV_RGB(c[0], c[1], c[2]), 1)
                cv.Circle(display_image, center_point, 10,
                          cv.CV_RGB(c[0], c[1], c[2]), 2)
                cv.Circle(display_image, center_point, 5,
                          cv.CV_RGB(c[0], c[1], c[2]), 3)

            #print "min_size is: " + str(min_size)
            # Listen for ESC or ENTER key
            c = cv.WaitKey(7) % 0x100
            if c == 27 or c == 10:
                break

            # Toggle which image to show
            if chr(c) == 'd':
                image_index = (image_index + 1) % len(image_list)

            image_name = image_list[image_index]
            image_name = "display"
            # for black and white: Threshold
            #for colored = display

            # Display frame to user
            if image_name == "camera":
                image = camera_image
                cv.PutText(image, "Camera (Normal)", text_coord, text_font,
                           text_color)
            elif image_name == "difference":
                image = difference
                cv.PutText(image, "Difference Image", text_coord, text_font,
                           text_color)
            elif image_name == "display":
                image = display_image
                cv.PutText(image, "Targets (w/AABBs and contours)", text_coord,
                           text_font, text_color)
            elif image_name == "threshold":
                # Convert the image to color.
                cv.CvtColor(grey_image, display_image, cv.CV_GRAY2RGB)
                image = display_image  # Re-use display image here
                cv.PutText(image, "Motion Mask", text_coord, text_font,
                           text_color)
            elif image_name == "faces":
                # Do face detection
                detect_faces(camera_image, haar_cascade, mem_storage)
                image = camera_image  # Re-use camera image here
                cv.PutText(image, "Face Detection", text_coord, text_font,
                           text_color)

            cv.ShowImage("Target", image)

            if self.writer:
                cv.WriteFrame(self.writer, image)

            arr = numpy.asarray(image[:, :])
            move_thresh = 100
            counter = 0

            # If only using a camera, then there is no time.sleep() needed,
            # because the camera clips us to 15 fps.  But if reading from a file,
            # we need this to keep the time-based target clipping correct:
            frame_t1 = time.time()

            centroid = get_centroid(trimmed_center_points)
            print 'centroid = ', centroid

            # If reading from a file, put in a forced delay:
            if not self.writer:
                delta_t = frame_t1 - frame_t0
                if delta_t < (1.0 / 15.0): time.sleep((1.0 / 15.0) - delta_t)

        t1 = time.time()
        time_delta = t1 - t0
        processed_fps = float(frame_count) / time_delta
        print "Got %d frames. %.1f s. %f fps." % (frame_count, time_delta,
                                                  processed_fps)
Ejemplo n.º 26
0
    def detect_motion(self, sensitivity='medium'):

        #Finding Video Size from the first frame
        frame = cv.QueryFrame(self.video_handle)
        frame_size = cv.GetSize(frame)
        '''Initializing Image Variables(to be used in motion detection) with required types and sizes'''
        # Image containg instantaneous moving rectangles
        color_image = cv.CreateImage(frame_size, 8, 3)
        # Resizing to window size
        color_output = cv.CreateImage(self.window_size, 8, 3)
        # Grey Image used for contour detection
        grey_image = cv.CreateImage(frame_size, cv.IPL_DEPTH_8U, 1)
        # Image storing background (moving pixels are averaged over small time window)
        moving_average = cv.CreateImage(frame_size, cv.IPL_DEPTH_32F, 3)
        # Image for storing tracks resized to window size
        track_output = cv.CreateImage(self.window_size, cv.IPL_DEPTH_8U, 3)
        track_image, track_win = self.init_track_window(frame)

        def totuple(a):
            try:
                return tuple(totuple(i) for i in a)
            except TypeError:
                return a

        first = True
        # Infinite loop for continuous detection of motion
        while True:
            '''########## Pixelwise Detection of Motion in a frame ###########'''
            # Capturing Frame
            color_image = cv.QueryFrame(self.video_handle)

            ##### Sensitivity Control 1 #####
            if (sensitivity == 'medium') or (sensitivity == 'low'):
                # Gaussian Smoothing
                cv.Smooth(color_image, color_image, cv.CV_GAUSSIAN, 3, 0)

            if first:
                difference = cv.CloneImage(color_image)
                temp = cv.CloneImage(color_image)
                cv.ConvertScale(color_image, moving_average, 1.0, 0.0)
                first = False
            else:
                cv.RunningAvg(color_image, moving_average, .020, None)

            # Convert the scale of the moving average.
            cv.ConvertScale(moving_average, temp, 1, 0.0)

            # Minus the current frame from the moving average.
            cv.AbsDiff(color_image, temp, difference)
            #cv.ShowImage("BG",difference)

            # Convert the image to grayscale.
            cv.CvtColor(difference, grey_image, cv.CV_RGB2GRAY)

            ##### Sensitivity Control 2 #####
            sens_thres = 90 if (sensitivity == 'low') or (self.opt
                                                          == 'cam') else 40
            # Convert the image to black and white.
            cv.Threshold(grey_image, grey_image, sens_thres, 255,
                         cv.CV_THRESH_BINARY)
            '''### Blobing moved adjacent pixels, finding closed contours and bounding rectangles ###'''
            ##### Sensitivity Control 3 #####
            if (sensitivity == 'medium') or (sensitivity == 'low'):
                # Dilate and erode to get people blobs
                ker_size = 20 if self.opt == 'file' else 50
                cv.Dilate(grey_image, grey_image, None, ker_size)
                cv.Erode(grey_image, grey_image, None, 3)

            storage = cv.CreateMemStorage(0)
            contour = cv.FindContours(grey_image, storage, cv.CV_RETR_CCOMP,
                                      cv.CV_CHAIN_APPROX_SIMPLE)
            points = []
            while contour:
                bound_rect = cv.BoundingRect(list(contour))
                polygon_points = cv.ApproxPoly(list(contour), storage,
                                               cv.CV_POLY_APPROX_DP)

                pt1 = (bound_rect[0], bound_rect[1])
                pt2 = (bound_rect[0] + bound_rect[2],
                       bound_rect[1] + bound_rect[3])

                if (self.opt == 'file'):
                    points.append(pt1)
                    points.append(pt2)
                elif (bound_rect[0] - bound_rect[2] >
                      20) and (bound_rect[1] - bound_rect[3] > 20):
                    points.append(pt1)
                    points.append(pt2)

                box = cv.MinAreaRect2(polygon_points)
                box2 = cv.BoxPoints(box)
                box3 = np.int0(np.around(box2))
                box4 = totuple(box3)
                box5 = box4 + (box4[0], )

                # Filling the contours in the greyscale image (visual blobs instead of just contours)
                cv.FillPoly(grey_image, [
                    list(polygon_points),
                ], cv.CV_RGB(255, 255, 255), 0, 0)

                # Following line to draw detected contours as well
                #cv.PolyLine( color_image, [ polygon_points, ], 0, cv.CV_RGB(255,0,0), 1, 0, 0 )

                # Drawing Rectangle around the detected contour
                cv.PolyLine(color_image, [list(box5)], 0, (0, 255, 255), 2)

                if len(points):  # (self.opt == 'file') and
                    center1 = (pt1[0] + pt2[0]) / 2
                    center2 = (pt1[1] + pt2[1]) / 2
                    cv.Circle(color_image, (center1, center2), 5,
                              cv.CV_RGB(0, 255, 0), -1)
                    rad = 3 if self.opt == 'file' else 5
                    cv.Circle(track_image, (center1, center2), rad,
                              cv.CV_RGB(255, 128, 0), -1)

                contour = contour.h_next()

            # Uncomment to track centroid of all the moved boxes (only for WebCam)
            '''
            if (self.opt == 'cam') and len(points):
                center_point = reduce(lambda a, b: ((a[0] + b[0]) / 2, (a[1] + b[1]) / 2), points)
                cv.Circle(track_image, center_point, 15, cv.CV_RGB(255, 128, 0), -1)
            '''
            cv.Resize(color_image, color_output, cv.CV_INTER_AREA)
            cv.ShowImage("Original", color_output)

            cv.Resize(track_image, track_output, cv.CV_INTER_AREA)
            cv.ShowImage(track_win, track_output)

            # Listen for ESC key
            c = cv.WaitKey(7) % 0x100
            if (0xFF & c == 27):
                cv.SaveImage('Tracks_img_042_' + sensitivity + '.jpeg',
                             track_output)
                break
Ejemplo n.º 27
0
    def run(self):
        frame = cv.QueryFrame(self.capture)
        frame_size = cv.GetSize(frame)

        # Capture the first frame from webcam for image properties
        display_image = cv.QueryFrame(self.capture)

        # Greyscale image, thresholded to create the motion mask:
        grey_image = cv.CreateImage(cv.GetSize(frame), cv.IPL_DEPTH_8U, 1)

        # The RunningAvg() function requires a 32-bit or 64-bit image...
        running_average_image = cv.CreateImage(cv.GetSize(frame),
                                               cv.IPL_DEPTH_32F, 3)
        # ...but the AbsDiff() function requires matching image depths:
        running_average_in_display_color_depth = cv.CloneImage(display_image)

        # RAM used by FindContours():
        mem_storage = cv.CreateMemStorage(0)

        # The difference between the running average and the current frame:
        difference = cv.CloneImage(display_image)

        target_count = 1
        last_target_count = 1
        last_target_change_t = 0.0
        k_or_guess = 1
        codebook = []
        frame_count = 0
        last_frame_entity_list = []

        t0 = time.time()

        # For toggling display:
        image_list = ["display", "difference", "threshold", "camera", "faces"]
        image_index = 0  # Index into image_list

        # Prep for text drawing:
        text_font = cv.InitFont(cv.CV_FONT_HERSHEY_COMPLEX, .5, .5, 0.0, 1,
                                cv.CV_AA)
        text_coord = (5, 15)
        text_color = cv.CV_RGB(255, 255, 255)

        haar_cascade = cv.Load(
            '/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml'
        )

        max_targets = 3

        while True:

            camera_image = cv.QueryFrame(self.capture)

            frame_count += 1
            frame_t0 = time.time()

            # Create an image with interactive feedback:
            display_image = cv.CloneImage(camera_image)

            # Create a working "color image" to modify / blur
            color_image = cv.CloneImage(display_image)

            # Smooth to get rid of false positives
            cv.Smooth(color_image, color_image, cv.CV_GAUSSIAN, 19, 0)

            # Use the Running Average as the static background
            # a = 0.020 leaves artifacts lingering way too long.
            # a = 0.320 works well at 320x240, 15fps.  (1/a is roughly num frames.)
            cv.RunningAvg(color_image, running_average_image, 0.420, None)

            # Convert the scale of the moving average.
            cv.ConvertScale(running_average_image,
                            running_average_in_display_color_depth, 1.0, 0.0)

            # Subtract the current frame from the moving average.
            cv.AbsDiff(color_image, running_average_in_display_color_depth,
                       difference)

            # Convert the image to greyscale.
            cv.CvtColor(difference, grey_image, cv.CV_RGB2GRAY)

            # Threshold the image to a black and white motion mask:
            cv.Threshold(grey_image, grey_image, 2, 255, cv.CV_THRESH_BINARY)
            # Smooth and threshold again to eliminate "sparkles"
            cv.Smooth(grey_image, grey_image, cv.CV_GAUSSIAN, 19, 0)
            cv.Threshold(grey_image, grey_image, 240, 255, cv.CV_THRESH_BINARY)
            cv.Dilate(grey_image, grey_image, None, 18)
            cv.Erode(grey_image, grey_image, None, 20)

            grey_image_as_array = numpy.asarray(cv.GetMat(grey_image))
            non_black_coords_array = numpy.where(grey_image_as_array > 3)
            # Convert from numpy.where()'s two separate lists to one list of (x, y) tuples:
            non_black_coords_array = zip(non_black_coords_array[1],
                                         non_black_coords_array[0])

            points = [
            ]  # Was using this to hold either pixel coords or polygon coords.
            bounding_box_list = []

            # Now calculate movements using the white pixels as "motion" data
            contour = cv.FindContours(grey_image, mem_storage,
                                      cv.CV_RETR_CCOMP,
                                      cv.CV_CHAIN_APPROX_SIMPLE)

            while contour:

                bounding_rect = cv.BoundingRect(list(contour))
                point1 = (bounding_rect[0], bounding_rect[1])
                point2 = (bounding_rect[0] + bounding_rect[2],
                          bounding_rect[1] + bounding_rect[3])

                bounding_box_list.append((point1, point2))
                polygon_points = cv.ApproxPoly(list(contour), mem_storage,
                                               cv.CV_POLY_APPROX_DP)

                # To track polygon points only (instead of every pixel):
                #points += list(polygon_points)

                # Draw the contours:
                levels = 0
                cv.DrawContours(color_image, contour, cv.CV_RGB(255, 0, 0),
                                cv.CV_RGB(0, 255, 0), levels, 3, 0, (0, 0))
                cv.FillPoly(grey_image, [
                    list(polygon_points),
                ], cv.CV_RGB(255, 255, 255), 0, 0)
                cv.PolyLine(display_image, [
                    polygon_points,
                ], 0, cv.CV_RGB(255, 255, 255), 1, 0, 0)
                #cv.Rectangle( display_image, point1, point2, cv.CV_RGB(120,120,120), 1)

                contour = contour.h_next()

            # Find the average size of the bbox (targets), then
            # remove any tiny bboxes (which are prolly just noise).
            # "Tiny" is defined as any box with 1/10th the area of the average box.
            # This reduces false positives on tiny "sparkles" noise.
            box_areas = []
            for box in bounding_box_list:
                box_width = box[right][0] - box[left][0]
                box_height = box[bottom][0] - box[top][0]
                box_areas.append(box_width * box_height)

                #cv.Rectangle( display_image, box[0], box[1], cv.CV_RGB(255,0,0), 1)

            average_box_area = 0.0
            if len(box_areas):
                average_box_area = float(sum(box_areas)) / len(box_areas)

            trimmed_box_list = []
            for box in bounding_box_list:
                box_width = box[right][0] - box[left][0]
                box_height = box[bottom][0] - box[top][0]

                # Only keep the box if it's not a tiny noise box:
                if (box_width * box_height) > average_box_area * 0.1:
                    trimmed_box_list.append(box)

            # Draw the trimmed box list:
            #for box in trimmed_box_list:
            #	cv.Rectangle( display_image, box[0], box[1], cv.CV_RGB(0,255,0), 2 )

            bounding_box_list = merge_collided_bboxes(trimmed_box_list)

            # Draw the merged box list:
            for box in bounding_box_list:
                cv.Rectangle(display_image, box[0], box[1],
                             cv.CV_RGB(0, 255, 0), 1)

            # Here are our estimate points to track, based on merged & trimmed boxes:
            estimated_target_count = len(bounding_box_list)

            if frame_t0 - last_target_change_t < .650:  # 1 change per 0.35 secs
                estimated_target_count = last_target_count
            else:
                if last_target_count - estimated_target_count > 1:
                    estimated_target_count = last_target_count - 1
                if estimated_target_count - last_target_count > 1:
                    estimated_target_count = last_target_count + 1
                last_target_change_t = frame_t0

            # Clip to the user-supplied maximum:
            estimated_target_count = min(estimated_target_count, max_targets)
            points = non_black_coords_array
            center_points = []

            if len(points):

                k_or_guess = max(estimated_target_count,
                                 1)  # Need at least one target to look for.
                if len(codebook) == estimated_target_count:
                    k_or_guess = codebook

                #points = vq.whiten(array( points ))  # Don't do this!  Ruins everything.
                codebook, distortion = vq.kmeans(array(points), k_or_guess)

                # Convert to tuples (and draw it to screen)
                for center_point in codebook:
                    center_point = (int(center_point[0]), int(center_point[1]))
                    center_points.append(center_point)
            trimmed_center_points = []
            removed_center_points = []

            for box in bounding_box_list:
                # Find the centers within this box:
                center_points_in_box = []

                for center_point in center_points:
                    if center_point[0] < box[right][0] and center_point[0] > box[left][0] and \
                     center_point[1] < box[bottom][1] and center_point[1] > box[top][1] :

                        # This point is within the box.
                        center_points_in_box.append(center_point)

                # Now see if there are more than one.  If so, merge them.
                if len(center_points_in_box) > 1:
                    # Merge them:
                    x_list = y_list = []
                    for point in center_points_in_box:
                        x_list.append(point[0])
                        y_list.append(point[1])

                    average_x = int(float(sum(x_list)) / len(x_list))
                    average_y = int(float(sum(y_list)) / len(y_list))

                    trimmed_center_points.append((average_x, average_y))

                    # Record that they were removed:
                    removed_center_points += center_points_in_box

                if len(center_points_in_box) == 1:
                    trimmed_center_points.append(
                        center_points_in_box[0])  # Just use it.

            # If there are any center_points not within a bbox, just use them.
            # (It's probably a cluster comprised of a bunch of small bboxes.)
            for center_point in center_points:
                if (not center_point in trimmed_center_points) and (
                        not center_point in removed_center_points):
                    trimmed_center_points.append(center_point)

            # Determine if there are any new (or lost) targets:
            actual_target_count = len(trimmed_center_points)
            last_target_count = actual_target_count

            # Now build the list of physical entities (objects)
            this_frame_entity_list = []

            # An entity is list: [ name, color, last_time_seen, last_known_coords ]

            for target in trimmed_center_points:

                # Is this a target near a prior entity (same physical entity)?
                entity_found = False
                entity_distance_dict = {}

                for entity in last_frame_entity_list:

                    entity_coords = entity[3]
                    delta_x = entity_coords[0] - target[0]
                    delta_y = entity_coords[1] - target[1]

                    distance = sqrt(pow(delta_x, 2) + pow(delta_y, 2))
                    entity_distance_dict[distance] = entity

                # Did we find any non-claimed entities (nearest to furthest):
                distance_list = entity_distance_dict.keys()
                distance_list.sort()

                for distance in distance_list:

                    # Yes; see if we can claim the nearest one:
                    nearest_possible_entity = entity_distance_dict[distance]

                    if nearest_possible_entity in this_frame_entity_list:
                        continue

                    # Found the nearest entity to claim:
                    entity_found = True
                    nearest_possible_entity[
                        2] = frame_t0  # Update last_time_seen
                    nearest_possible_entity[
                        3] = target  # Update the new location
                    this_frame_entity_list.append(nearest_possible_entity)
                    break

                if entity_found == False:
                    # It's a new entity.
                    color = (random.randint(0, 255), random.randint(0, 255),
                             random.randint(0, 255))
                    name = hashlib.md5(str(frame_t0) +
                                       str(color)).hexdigest()[:6]
                    last_time_seen = frame_t0

                    new_entity = [name, color, last_time_seen, target]
                    this_frame_entity_list.append(new_entity)

            # Now "delete" any not-found entities which have expired:
            entity_ttl = 1.0  # 1 sec.

            ent_count = 0
            for entity in last_frame_entity_list:
                last_time_seen = entity[2]
                if frame_t0 - last_time_seen > entity_ttl:
                    pass
                else:
                    # Save it for next time... not expired yet:
                    this_frame_entity_list.append(entity)
                    ent_count += 1

            # For next frame:
            last_frame_entity_list = this_frame_entity_list

            # Draw the found entities to screen:
            count = 0
            if ent_count != 0:
                entity = this_frame_entity_list[0]
                center_point = entity[3]
                c = entity[1]  # RGB color tuple
                # print '%s %d %d %d' % (entity[0], count, center_point[0], center_point[1])
                cv.Circle(display_image, center_point, 20,
                          cv.CV_RGB(c[0], c[1], c[2]), 1)
                cv.Circle(display_image, center_point, 15,
                          cv.CV_RGB(c[0], c[1], c[2]), 1)
                cv.Circle(display_image, center_point, 10,
                          cv.CV_RGB(c[0], c[1], c[2]), 2)
                cv.Circle(display_image, center_point, 5,
                          cv.CV_RGB(c[0], c[1], c[2]), 3)

            text_font = cv.InitFont(cv.CV_FONT_HERSHEY_COMPLEX, .5, .5, 0.0, 1,
                                    cv.CV_AA)
            text_coord = (5, 15)
            text_color = cv.CV_RGB(255, 255, 255)

            x = 50 + (center_point[0] * 80 / 320)
            y = 20 + (center_point[1] * 80 / 240)
            if self.have_eye:
                self.ServoMove(0, int(x))
                self.ServoMove(1, int(y))

            s = '%3.0d %3.0d' % (x, y)
            cv.PutText(display_image, str(s), text_coord, text_font,
                       text_color)

            #print "min_size is: " + str(min_size)
            # Listen for ESC or ENTER key
            c = cv.WaitKey(7) % 0x100
            if c == 27 or c == 10:
                break

            # Toggle which image to show
            if chr(c) == 'd':
                image_index = (image_index + 1) % len(image_list)

            image_name = image_list[image_index]

            # Display frame to user
            if image_name == "display":
                image = display_image

# cv.PutText( image, "AABBs and contours", text_coord, text_font, text_color )
            elif image_name == "camera":
                image = camera_image
                cv.PutText(image, "No overlay", text_coord, text_font,
                           text_color)
            elif image_name == "difference":
                image = difference
                cv.PutText(image, "Difference Image", text_coord, text_font,
                           text_color)
            elif image_name == "faces":
                # Do face detection
                detect_faces(camera_image, haar_cascade, mem_storage)
                image = camera_image  # Re-use camera image here
                cv.PutText(image, "Face Detection", text_coord, text_font,
                           text_color)
            elif image_name == "threshold":
                # Convert the image to color.
                cv.CvtColor(grey_image, display_image, cv.CV_GRAY2RGB)
                image = display_image  # Re-use display image here
                cv.PutText(image, "Motion Mask", text_coord, text_font,
                           text_color)

            cv.ShowImage("Target", image)

            if self.writer:
                cv.WriteFrame(self.writer, image)

            frame_t1 = time.time()

        t1 = time.time()
        time_delta = t1 - t0
        processed_fps = float(frame_count) / time_delta
        print "Got %d frames. %.1f s. %f fps." % (frame_count, time_delta,
                                                  processed_fps)
Ejemplo n.º 28
0
Archivo: track.py Proyecto: Edsby/track
        boundingRect = cv.BoundingRect(list(contour))
        p1 = (boundingRect[0], boundingRect[1])
        p2 = (boundingRect[0] + boundingRect[2],
              boundingRect[1] + boundingRect[3])

        boundingBoxList.append((p1, p2))
        polygonPoints = cv.ApproxPoly(list(contour), memStorage,
                                      cv.CV_POLY_APPROX_DP)

        #Show the contours
        cv.FillPoly(greyImage, [
            list(polygonPoints),
        ], cv.CV_RGB(255, 255, 255), 0, 0)
        cv.PolyLine(displayImage, [
            polygonPoints,
        ], 0, cv.CV_RGB(255, 255, 255), 1, 0, 0)

        contour = contour.h_next()

    # Find the average size of the bounding box targets and remove ones that are 5% or less than the average as noise
    boxAreas = []
    for box in boundingBoxList:
        boxWidth = box[right][0] - box[left][0]
        boxHeight = box[bottom][0] - box[top][0]
        boxAreas.append(boxWidth * boxHeight)

    averageBoxArea = 0.0
    if len(boxAreas):
        averageBoxArea = float(sum(boxAreas) / len(boxAreas))
Ejemplo n.º 29
0
def find_biggest_region(pub):
    """ finds all the contours in threshed image, finds the largest of those,
        and then marks in in the main image
    """
    # get D so that we can change values in it
    global D

    # Create a copy image of thresholds then find contours on that image
    cv.Copy(D.threshed_image, D.copy)  # copy threshed image

    # this is OpenCV's call to find all of the contours:
    contours = cv.FindContours(D.copy, D.storage, cv.CV_RETR_EXTERNAL,
                               cv.CV_CHAIN_APPROX_SIMPLE)

    # Next we want to find the *largest* contour
    # this is the standard algorithm:
    #    walk the list of all contours, remembering the biggest so far:
    if len(contours) > 0:
        biggest = contours
        biggestArea = cv.ContourArea(contours)
        while contours != None:
            nextArea = cv.ContourArea(contours)
            if biggestArea < nextArea:
                biggest = contours
                biggestArea = nextArea
            contours = contours.h_next()

        # Use OpenCV to get a bounding rectangle for the largest contour
        br = cv.BoundingRect(biggest, update=0)

        # Draw a red box from (42,42) to (84,126), for now (you'll change this):
        x = br[0]
        y = br[1]
        w = br[2]
        h = br[3]
        upper_left = (x, y)
        lower_left = (x, y + h)
        lower_right = (x + w, y + h)
        upper_right = (x + w, y)

        cv.PolyLine(D.image,
                    [[upper_left, lower_left, lower_right, upper_right]], 1,
                    cv.RGB(255, 0, 0))

        # Draw the circle, at the image center for now (you'll change this)
        center = ((2 * x + w) / 2, (2 * y + h) / 2)
        cv.Circle(D.image,
                  center,
                  10,
                  cv.RGB(255, 255, 0),
                  thickness=2,
                  lineType=8,
                  shift=0)

        # Draw matching contours in white with inner ones in green
        cv.DrawContours(D.image,
                        biggest,
                        cv.RGB(255, 255, 255),
                        cv.RGB(0, 255, 0),
                        1,
                        thickness=2,
                        lineType=8,
                        offset=(0, 0))

        # publish the rectangle vertex coordinates
        pub.publish(','.join(map(str, [upper_left, lower_right])))
Ejemplo n.º 30
0
    def displayRobot(self, (x_mm, y_mm, theta_deg), color=ROBOT_COLOR_BGR, scale=1, line_thickness=1):

        # Get a polyline (e.g. triangle) to represent the robot icon
        robot_points = self.robot_polyline(scale)
        
        # Rotate the polyline by the current angle
        robot_points = map(lambda pt: rotate(pt, theta_deg), robot_points)
        
        # Convert the robot position from meters to pixels
        x_pix, y_pix = self.mm2pix(x_mm), self.mm2pix(y_mm)

        # Move the polyline to the current robot position
        robot_points = map(lambda pt: (x_pix+pt[0], y_pix+pt[1]), robot_points)
        
        # Add an icon for the robot
        cv.PolyLine(self.image, [robot_points], True, color, line_thickness) 

    def displayScan(self, scan, offset_mm = (0,0), color=SCANPOINT_COLOR_BGR):
   
       for point in scan:
           cv.Circle(self.image, (self.mm2pix(point[0]+offset_mm[0]), self.mm2pix(point[1]+offset_mm[1])), \
                     SCANPOINT_RADIUS, color)
      
               
    def displayVelocities(self, dxy_mm, dtheta_deg):
        
        # Add velocity bars
        self.show_velocity(dxy_mm,      SENSOR_V_MAX_MM,      '   dXY', SENSOR_V_Y)
        self.show_velocity(dtheta_deg,  SENSOR_THETA_MAX_DEG, 'dTheta', SENSOR_THETA_Y)
                       
    def displayTrajectory(self, trajectory):