예제 #1
0
def is_square(contour):
    """
    Squareness checker

    Square contours should:
        -have 4 vertices after approximation, 
        -have relatively large area (to filter out noisy contours)
        -be convex.
        -have angles between sides close to 90deg (cos(ang) ~0 )
    Note: absolute value of an area is used because area may be
    positive or negative - in accordance with the contour orientation
    """

    area = math.fabs( cv.ContourArea(contour) )
    isconvex = cv.CheckContourConvexity(contour)
    s = 0
    if len(contour) == 4 and area > 1000 and isconvex:
        for i in range(1, 4):
            # find minimum angle between joint edges (maximum of cosine)
            pt1 = contour[i]
            pt2 = contour[i-1]
            pt0 = contour[i-2]

            t = math.fabs(angle(pt0, pt1, pt2))
            if s <= t:s = t

        # if cosines of all angles are small (all angles are ~90 degree) 
        # then its a square
        if s < 0.3:return True

    return False       
예제 #2
0
    def somethingHasMoved(self):
        
        # Find contours
        storage = cv.CreateMemStorage(0)
        contours = cv.FindContours(self.gray_frame, storage, cv.CV_RETR_EXTERNAL, cv.CV_CHAIN_APPROX_SIMPLE)

        self.currentcontours = contours #Save contours
        
        while contours: #For all contours compute the area
            self.currentsurface += cv.ContourArea(contours)
            contours = contours.h_next()
        
        avg = (self.currentsurface*100)/self.surface #Calculate the average of contour area on the total size
        self.currentsurface = 0 #Put back the current surface to 0
        
        if avg > self.threshold:
            return True
        else:
            return False
예제 #3
0
    def verificaMovimento(self):
        """
        Obtem os contornos da imagem cinza e soma a area deles para verificar se ouve diferenca.
        Caso a soma da area dos contornos seja maior que o "0" retorna True, caso contrario False.
        """
        # Encontra os contornos dos objetos na imagem cinza.
        contornos = cv.FindContours(self.imagem_cinza, cv.CreateMemStorage(0))

        while contornos:
            self.area_corrente += cv.ContourArea(contornos)
            contornos = contornos.h_next()

        # Faco uma media da area corrente.
        movimentos = (self.area_corrente * 100) / self.area
        self.area_corrente = 0

        if movimentos > 0:
            return True
        else:
            return False
예제 #4
0
    def find(self, img):
        started = time.time()
        gray = self.Cached('gray', img.height, img.width, cv.CV_8UC1)
        cv.CvtColor(img, gray, cv.CV_BGR2GRAY)

        sobel = self.Cached('sobel', img.height, img.width, cv.CV_16SC1)
        sobely = self.Cached('sobely', img.height, img.width, cv.CV_16SC1)

        cv.Sobel(gray, sobel, 1, 0)
        cv.Sobel(gray, sobely, 0, 1)
        cv.Add(sobel, sobely, sobel)

        sobel8 = self.Cached('sobel8', sobel.height, sobel.width, cv.CV_8UC1)
        absnorm8(sobel, sobel8)
        cv.Threshold(sobel8, sobel8, 128.0, 255.0, cv.CV_THRESH_BINARY)

        sobel_integral = self.Cached('sobel_integral', img.height + 1,
                                     img.width + 1, cv.CV_32SC1)
        cv.Integral(sobel8, sobel_integral)

        d = 16
        _x1y1 = cv.GetSubRect(
            sobel_integral,
            (0, 0, sobel_integral.cols - d, sobel_integral.rows - d))
        _x1y2 = cv.GetSubRect(
            sobel_integral,
            (0, d, sobel_integral.cols - d, sobel_integral.rows - d))
        _x2y1 = cv.GetSubRect(
            sobel_integral,
            (d, 0, sobel_integral.cols - d, sobel_integral.rows - d))
        _x2y2 = cv.GetSubRect(
            sobel_integral,
            (d, d, sobel_integral.cols - d, sobel_integral.rows - d))

        summation = cv.CloneMat(_x2y2)
        cv.Sub(summation, _x1y2, summation)
        cv.Sub(summation, _x2y1, summation)
        cv.Add(summation, _x1y1, summation)
        sum8 = self.Cached('sum8', summation.height, summation.width,
                           cv.CV_8UC1)
        absnorm8(summation, sum8)
        cv.Threshold(sum8, sum8, 32.0, 255.0, cv.CV_THRESH_BINARY)

        cv.ShowImage("sum8", sum8)
        seq = cv.FindContours(sum8, cv.CreateMemStorage(), cv.CV_RETR_EXTERNAL)
        subimg = cv.GetSubRect(img, (d / 2, d / 2, sum8.cols, sum8.rows))
        t_cull = time.time() - started

        seqs = []
        while seq:
            seqs.append(seq)
            seq = seq.h_next()

        started = time.time()
        found = {}
        print 'seqs', len(seqs)
        for seq in seqs:
            area = cv.ContourArea(seq)
            if area > 1000:
                rect = cv.BoundingRect(seq)
                edge = int((14 / 14.) * math.sqrt(area) / 2 + 0.5)
                candidate = cv.GetSubRect(subimg, rect)
                sym = self.dm.decode(
                    candidate.width,
                    candidate.height,
                    buffer(candidate.tostring()),
                    max_count=1,
                    #min_edge = 6,
                    #max_edge = int(edge)      # Units of 2 pixels
                )
                if sym:
                    onscreen = [(d / 2 + rect[0] + x, d / 2 + rect[1] + y)
                                for (x, y) in self.dm.stats(1)[1]]
                    found[sym] = onscreen
                else:
                    print "FAILED"
        t_brute = time.time() - started
        print "cull took", t_cull, "brute", t_brute
        return found
    def run(self):
        # Capture first frame to get size
        frame = cv.QueryFrame(self.capture)
        frame_size = cv.GetSize(frame)

        width = frame.width
        height = frame.height
        surface = width * height  # Surface area of the image
        cursurface = 0  # Hold the current surface that have changed

        grey_image = cv.CreateImage(cv.GetSize(frame), cv.IPL_DEPTH_8U, 1)
        moving_average = cv.CreateImage(cv.GetSize(frame), cv.IPL_DEPTH_32F, 3)
        difference = None

        while True:
            color_image = cv.QueryFrame(self.capture)

            cv.Smooth(color_image, color_image, cv.CV_GAUSSIAN, 3,
                      0)  # Remove false positives

            if not difference:  # For the first time put values in difference, temp and moving_average
                difference = cv.CloneImage(color_image)
                temp = cv.CloneImage(color_image)
                cv.ConvertScale(color_image, moving_average, 1.0, 0.0)
            else:
                cv.RunningAvg(color_image, moving_average, 0.020,
                              None)  # Compute the average

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

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

            # Convert the image so that it can be thresholded
            cv.CvtColor(difference, grey_image, cv.CV_RGB2GRAY)
            cv.Threshold(grey_image, grey_image, 70, 255, cv.CV_THRESH_BINARY)

            cv.Dilate(grey_image, grey_image, None, 18)  # to get object blobs
            cv.Erode(grey_image, grey_image, None, 10)

            # Find contours
            storage = cv.CreateMemStorage(0)
            contours = cv.FindContours(grey_image, storage,
                                       cv.CV_RETR_EXTERNAL,
                                       cv.CV_CHAIN_APPROX_SIMPLE)

            backcontours = contours  # Save contours

            while contours:  # For all contours compute the area
                cursurface += cv.ContourArea(contours)
                contours = contours.h_next()

            avg = (
                cursurface * 100
            ) / surface  # Calculate the average of contour area on the total size
            if avg > self.ceil:
                print("Something is moving !")
                ring = IntrusionAlarm()
                ring.run()

            # print avg,"%"
            cursurface = 0  # Put back the current surface to 0

            # Draw the contours on the image
            _red = (0, 0, 255)
            # Red for external contours
            _green = (0, 255, 0)
            # Gren internal contours
            levels = 1  # 1 contours drawn, 2 internal contours as well, 3 ...
            cv.DrawContours(color_image, backcontours, _red, _green, levels, 2,
                            cv.CV_FILLED)

            cv.ShowImage("Virtual Eye", color_image)

            # Listen for ESC or ENTER key
            c = cv.WaitKey(7) % 0x100
            if c == 27 or c == 10:
                break
            elif c == 99:
                cv2.destroyWindow('Warning!!!')
예제 #6
0
    def somethingHasMoved(self):

        # Find contours
        storage = cv.CreateMemStorage(0)
        contours = cv.FindContours(self.gray_frame, storage, cv.CV_RETR_EXTERNAL, cv.CV_CHAIN_APPROX_SIMPLE)

        #cv.ShowImage("Image", self.gray_frame)
        #print(self.gray_frame.width)
        #print(self.gray_frame.height)
        
        alto = self.gray_frame.height
        ancho = self.gray_frame.width
        q0 = self.gray_frame[ :ancho/2, :alto/2 ]
        q1 = self.gray_frame[ ancho/2:, :alto/2 ]
        q2 = self.gray_frame[ :ancho/2, alto/2: ]
        q3 = self.gray_frame[ ancho/2:, alto/2: ]

        q0nz = np.count_nonzero(q0)
        q1nz = np.count_nonzero(q1)
        q2nz = np.count_nonzero(q2)
        q3nz = np.count_nonzero(q3)

        sys.stdout.write("\033[F") #back to previous line
        sys.stdout.write("\033[K") #clear line
        sys.stdout.write("\033[F") #back to previous line
        sys.stdout.write("\033[K") #clear line
        sys.stdout.write("\033[F") #back to previous line
        sys.stdout.write("\033[K") #clear line
        if q0nz or q1nz or q2nz or q3nz:
            print("Algo se mueve !")
                #cambio de estado
            if q0nz != self.m0:
                self.m0 = q0nz
                self.mqtt.publish("0:%i" % (self.m0), 'camaras')
            if q1nz != self.m1:
                self.m1 = q1nz
                self.mqtt.publish("1:%i" % (self.m1), 'camaras')
            if q2nz != self.m2:
                self.m2 = q2nz
                self.mqtt.publish("3:%i" % (self.m2), 'camaras')
            if q3nz != self.m3:
                self.m3 = q3nz
                self.mqtt.publish("2:%i" % (self.m3), 'camaras')
        else:
            print("")
        print("{0} {1}\n{2} {3}".format(blockchar(q0nz),blockchar(q2nz),blockchar(q1nz),blockchar(q3nz)))
        

        self.currentcontours = contours #Save contours

        while contours: #For all contours compute the area
            self.currentsurface += cv.ContourArea(contours)
            contours = contours.h_next()

        avg = (self.currentsurface*100)/self.surface #Calculate the average of contour area on the total size
        self.currentsurface = 0 #Put back the current surface to 0

        #print(avg)
        if avg > self.threshold:
            return True
        else:
            return False
예제 #7
0
파일: liner.py 프로젝트: jgrip/xystitch
    def try_contour(self):
        self.total_contours += 1
        self.contouri += 1
        self.contour_area = cv.ContourArea(self.cur_contour)
        dbg('Thresh contour %d' % self.contouri, level=2)
        if self.filter():
            dbg('  Rejected: filtered contour b/c area not %f <= %f <= %f' %
                (self.min_area, self.contour_area, self.max_area))
            if draw_thresh_contours:
                # Purple
                cv.PolyLine(self.contours_map, [self.cur_contour], True,
                            cv.CV_RGB(128, 0, 128))
            return

        self.checked_contours += 1
        #if contouri != 5:
        #    continue
        #print '  Points:'
        #print_contour(contour, '    ')
        contour_len_ = contour_len(self.cur_contour)
        dbg('  len %f' % contour_len_, level=2)
        dbg('  area %f' % self.contour_area, level=2)
        if contour_len_ < self.min_len:
            dbg('  Rejected: did not meet minimum length w/ %f < %f' %
                (contour_len_, self.min_len),
                level=2)
            if draw_thresh_contours:
                # red
                cv.PolyLine(self.contours_map, [self.cur_contour], True,
                            cv.CV_RGB(255, 0, 0))
            return

        this_diff = contour_line_diff(self.cur_contour, self.line)
        dbg('  diff %f' % this_diff, level=2)
        if this_diff >= self.best_diff:
            dbg("  Rejected: worse diff %f >= %f" %
                (this_diff, self.best_diff),
                level=2)
            if draw_thresh_contours:
                # Teal
                cv.PolyLine(self.contours_map, [self.cur_contour], True,
                            cv.CV_RGB(0, 128, 128))
            return
        hist_diff = self.compare_ref(self.cur_contour)
        dbg("  Hist diff: %f" % hist_diff, level=2)
        # 0.95 was too lose
        if hist_diff < 0.90:
            dbg("  Rejected: poor histogram match", level=2)
            if draw_thresh_contours:
                # Yellow
                #cv.PolyLine(self.contours_map, [self.cur_contour], True, cv.CV_RGB(255, 255, 0) )
                cv.PolyLine(
                    self.contours_map, [self.cur_contour], True,
                    cv.CV_RGB(random.randint(0, 256), random.randint(0, 256),
                              random.randint(0, 256)))
            return
        dbg('  Accepted: new best contour', level=2)
        self.best_contour = self.cur_contour
        self.best_thresh = self.cur_thresh
        self.best_diff = this_diff
        self.best_hist_diff = hist_diff
        #draw_contour(self.cur_contour)
        if draw_thresh_contours:
            # green
            cv.PolyLine(self.contours_map, [self.cur_contour], True,
                        cv.CV_RGB(0, 255, 0))
def compare_2_formes(Image1, Image2):
    mincontour = 500  # minimum size of a form to be detected
    CVCONTOUR_APPROX_LEVEL = 5  # parameter for call contour
    img_edge1 = cv.CreateImage(cv.GetSize(Image1), 8, 1)  #egde image

    #        img1_8uc3=cv.CreateImage(cv.GetSize(Image1),8,3)

    img_edge2 = cv.CreateImage(cv.GetSize(Image2), 8, 1)
    #       img2_8uc3=cv.CreateImage(cv.GetSize(Image2),8,3)

    cv.Threshold(Image1, img_edge1, 123, 255,
                 cv.CV_THRESH_BINARY)  # filter threshold
    cv.Threshold(Image2, img_edge2, 123, 255, cv.CV_THRESH_BINARY)

    storage1 = cv.CreateMemStorage()
    storage2 = cv.CreateMemStorage()

    first_contour1 = cv.FindContours(
        img_edge1, storage1)  # pointer to the first edge of the form 1
    first_contour2 = cv.FindContours(
        img_edge2, storage2)  # pointer to the first edge of the form 2

    newseq = first_contour1
    newseq2 = first_contour2

    if not (first_contour1) or not (first_contour2):
        return 0

    current_contour = first_contour1
    while 1:
        current_contour = current_contour.h_next(
        )  # path in the sequence of edges of the first form
        if (not (current_contour)
            ):  # stop condition if the contour pointer = NULL
            break

        if cv.ContourArea(current_contour) > mincontour:
            newseq = cv.ApproxPoly(current_contour, storage1,
                                   cv.CV_POLY_APPROX_DP,
                                   CVCONTOUR_APPROX_LEVEL, 0)
    #          cv.CvtColor(Image1,img1_8uc3,cv.CV_GRAY2BGR );
    #          cv.DrawContours(img1_8uc3,newseq,cv.CV_RGB(0,255,0),cv.CV_RGB(255,0,0),0,2,8);
    #          cv.NamedWindow("ContourImage2",cv.CV_WINDOW_AUTOSIZE)
    #          cv.ShowImage("ContourImage2",img1_8uc3)

    current_contour = first_contour2

    # path of the second form of contours
    while 1:
        current_contour = current_contour.h_next()
        if (not (current_contour)):
            break

        if cv.ContourArea(current_contour) > mincontour:
            newseq2 = cv.ApproxPoly(current_contour, storage2,
                                    cv.CV_POLY_APPROX_DP,
                                    CVCONTOUR_APPROX_LEVEL, 0)
    #          cv.CvtColor(Image2,img2_8uc3,cv.CV_GRAY2BGR);
    #          cv.DrawContours(img2_8uc3,newseq2,cv.CV_RGB(0,255,0),cv.CV_RGB(255,0,0),0,2,8);
    #          cv.NamedWindow("ContourImage",cv.CV_WINDOW_AUTOSIZE)
    #          cv.ShowImage("ContourImage",img2_8uc3)

    matchresult = 1
    matchresult = cv.MatchShapes(newseq, newseq2, 1, 2)
    return matchresult
예제 #9
0
def findSquares4(img, storage):
    N = 11
    sz = (img.width & -2, img.height & -2)
    timg = cv.CloneImage(img); # make a copy of input image
    gray = cv.CreateImage(sz, 8, 1)
    pyr = cv.CreateImage((sz.width/2, sz.height/2), 8, 3)
    # create empty sequence that will contain points -
    # 4 points per square (the square's vertices)
    squares = cv.CreateSeq(0, sizeof_CvSeq, sizeof_CvPoint, storage)
    squares = CvSeq_CvPoint.cast(squares)

    # select the maximum ROI in the image
    # with the width and height divisible by 2
    subimage = cv.GetSubRect(timg, cv.Rect(0, 0, sz.width, sz.height))

    # down-scale and upscale the image to filter out the noise
    cv.PyrDown(subimage, pyr, 7)
    cv.PyrUp(pyr, subimage, 7)
    tgray = cv.CreateImage(sz, 8, 1)
    # find squares in every color plane of the image
    for c in range(3):
        # extract the c-th color plane
        channels = [None, None, None]
        channels[c] = tgray
        cv.Split(subimage, channels[0], channels[1], channels[2], None)
        for l in range(N):
            # hack: use Canny instead of zero threshold level.
            # Canny helps to catch squares with gradient shading
            if(l == 0):
                # apply Canny. Take the upper threshold from slider
                # and set the lower to 0 (which forces edges merging)
                cv.Canny(tgray, gray, 0, thresh, 5)
                # dilate canny output to remove potential
                # holes between edge segments
                cv.Dilate(gray, gray, None, 1)
            else:
                # apply threshold if l!=0:
                #     tgray(x, y) = gray(x, y) < (l+1)*255/N ? 255 : 0
                cv.Threshold(tgray, gray, (l+1)*255/N, 255, cv.CV_THRESH_BINARY)

            # find contours and store them all as a list
            count, contours = cv.FindContours(gray, storage, sizeof_CvContour,
                cv.CV_RETR_LIST, cv. CV_CHAIN_APPROX_SIMPLE, (0, 0))

            if not contours:
                continue

            # test each contour
            for contour in contours.hrange():
                # approximate contour with accuracy proportional
                # to the contour perimeter
                result = cv.ApproxPoly(contour, sizeof_CvContour, storage,
                    cv.CV_POLY_APPROX_DP, cv.ContourPerimeter(contours)*0.02, 0)
                # square contours should have 4 vertices after approximation
                # relatively large area (to filter out noisy contours)
                # and be convex.
                # Note: absolute value of an area is used because
                # area may be positive or negative - in accordance with the
                # contour orientation
                if(result.total == 4 and
                    abs(cv.ContourArea(result)) > 1000 and
                    cv.CheckContourConvexity(result)):
                    s = 0
                    for i in range(5):
                        # find minimum angle between joint
                        # edges (maximum of cosine)
                        if(i >= 2):
                            t = abs(angle(result[i], result[i-2], result[i-1]))
                            if s<t:
                                s=t
                    # if cosines of all angles are small
                    # (all angles are ~90 degree) then write quandrange
                    # vertices to resultant sequence
                    if(s < 0.3):
                        for i in range(4):
                            squares.append(result[i])

    return squares