Example #1
0
def findImageContour(img, frame):
    storage = cv.CreateMemStorage()
    cont = cv.FindContours(img, storage, cv.CV_RETR_EXTERNAL,
                           cv.CV_CHAIN_APPROX_NONE, (0, 0))
    max_center = [None, 0]
    for c in contour_iterator(cont):
        # Number of points must be more than or equal to 6 for cv.FitEllipse2
        # Use to set minimum size of object to be tracked.
        if len(c) >= 60:
            # Copy the contour into an array of (x,y)s
            PointArray2D32f = cv.CreateMat(1, len(c), cv.CV_32FC2)
            for (i, (x, y)) in enumerate(c):
                PointArray2D32f[0, i] = (x, y)
                # Fits ellipse to current contour.
                (center, size, angle) = cv.FitEllipse2(PointArray2D32f)
                # Only consider location of biggest contour  -- adapt for multiple object tracking
            if size > max_center[1]:
                max_center[0] = center
                max_center[1] = size
                angle = angle

            if True:
                # Draw the current contour in gray
                gray = cv.CV_RGB(255, 255, 255)
                cv.DrawContours(img, c, gray, gray, 0, 1, 8, (0, 0))

    if max_center[1] > 0:
        # Convert ellipse data from float to integer representation.
        center = (cv.Round(max_center[0][0]), cv.Round(max_center[0][1]))
        size = (cv.Round(max_center[1][0] * 0.5),
                cv.Round(max_center[1][1] * 0.5))
        color = cv.CV_RGB(255, 0, 0)

        cv.Ellipse(frame, center, size, angle, 0, 360, color, 3, cv.CV_AA, 0)
Example #2
0
    def track_keypoints(self, grey, prev_grey):
        # We are tracking points between the previous frame and the
        # current frame
        img0, img1 = prev_grey, grey

        # Reshape the current keypoints into a numpy array required
        # by calcOpticalFlowPyrLK()
        p0 = np.float32([p for p in self.keypoints]).reshape(-1, 1, 2)

        # Calculate the optical flow from the previous frame to the current frame
        p1, st, err = cv2.calcOpticalFlowPyrLK(img0, img1, p0, None,
                                               **self.lk_params)

        # Do the reverse calculation: from the current frame to the previous frame
        try:
            p0r, st, err = cv2.calcOpticalFlowPyrLK(img1, img0, p1, None,
                                                    **self.lk_params)

            # Compute the distance between corresponding points in the two flows
            d = abs(p0 - p0r).reshape(-1, 2).max(-1)

            # If the distance between pairs of points is < 1 pixel, set
            # a value in the "good" array to True, otherwise False
            good = d < 1

            # Initialize a list to hold new keypoints
            new_keypoints = list()

            # Cycle through all current and new keypoints and only keep
            # those that satisfy the "good" condition above
            for (x, y), good_flag in zip(p1.reshape(-1, 2), good):
                if not good_flag:
                    continue
                new_keypoints.append((x, y))

                # Draw the keypoint on the image
                cv2.circle(self.marker_image, (x, y), self.feature_size,
                           (0, 255, 0, 0), cv.CV_FILLED, 8, 0)

            # Set the global keypoint list to the new list
            self.keypoints = new_keypoints

            # If we have enough points, find the best fit ellipse around them
            if len(self.keypoints) > 6:
                self.keypoints_matrix = cv.CreateMat(1, len(self.keypoints),
                                                     cv.CV_32SC2)
                i = 0
                for p in self.keypoints:
                    cv.Set2D(self.keypoints_matrix, 0, i,
                             (int(p[0]), int(p[1])))
                    i = i + 1
                track_box = cv.FitEllipse2(self.keypoints_matrix)
            else:
                # Otherwise, find the best fitting rectangle
                track_box = cv2.boundingRect(self.keypoints_matrix)
        except:
            track_box = None

        return track_box
Example #3
0
    def process_image(self, slider_pos):
        """
        This function finds contours, draws them and their approximation by ellipses.
        """
        stor = cv.CreateMemStorage()

        # Create the destination images
        image02 = cv.CloneImage(self.source_image)
        cv.Zero(image02)
        image04 = cv.CreateImage(cv.GetSize(self.source_image),
                                 cv.IPL_DEPTH_8U, 3)
        cv.Zero(image04)

        # Threshold the source image. This needful for cv.FindContours().
        cv.Threshold(self.source_image, image02, slider_pos, 255,
                     cv.CV_THRESH_BINARY)

        # Find all contours.
        cont = cv.FindContours(image02, stor, cv.CV_RETR_LIST,
                               cv.CV_CHAIN_APPROX_NONE, (0, 0))

        for c in contour_iterator(cont):
            # Number of points must be more than or equal to 6 for cv.FitEllipse2
            if len(c) >= 6:
                # Copy the contour into an array of (x,y)s
                PointArray2D32f = cv.CreateMat(1, len(c), cv.CV_32FC2)
                for (i, (x, y)) in enumerate(c):
                    PointArray2D32f[0, i] = (x, y)

                # Draw the current contour in gray
                gray = cv.CV_RGB(100, 100, 100)
                cv.DrawContours(image04, c, gray, gray, 0, 1, 8, (0, 0))

                # Fits ellipse to current contour.
                (center, size, angle) = cv.FitEllipse2(PointArray2D32f)

                # Convert ellipse data from float to integer representation.
                center = (cv.Round(center[0]), cv.Round(center[1]))
                size = (cv.Round(size[0] * 0.5), cv.Round(size[1] * 0.5))

                # Draw ellipse in random color
                color = cv.CV_RGB(random.randrange(256), random.randrange(256),
                                  random.randrange(256))
                cv.Ellipse(image04, center, size, angle, 0, 360, color, 2,
                           cv.CV_AA, 0)

        # Show image. HighGUI use.
        cv.ShowImage("Result", image04)
Example #4
0
def centerRadius(cvImg, ColorLower=None, ColorUpper=None):
    lowerBound = cv.Scalar(90, 0, 90)
    upperBound = cv.Scalar(171, 80, 171)
    size = cv.GetSize(cvImg)
    output = cv.CreateMat(size[0], size[1], cv.CV_8UC1)
    cv.InRangeS(cvImg, lowerBound, upperBound, output)

    yi, xi = np.nonzero(output)
    #points = np.array([xi,yi]).T
    #coords = [tuple(points[pt]) for pt in range(len(points))]
    coords = zip(xi, yi)
    PointArray2D32f = cv.CreateMat(1, len(coords), cv.CV_32FC2)
    for (i, (x, y)) in enumerate(coords):
        PointArray2D32f[0, i] = (x, y)
    (center, size, angle) = cv.FitEllipse2(PointArray2D32f)
    h, k = center
    radius = np.sqrt(np.power((xi[0] - h), 2) + np.power(yi[0] - k, 2))
    return tuple(np.around([h, k])), round(radius)
    def process_image(self, slider_pos):
        global cimg, source_image1, ellipse_size, maxf, maxs, eoc, lastcx, lastcy, lastr
        """
        This function finds contours, draws them and their approximation by ellipses.
        """
        stor = cv.CreateMemStorage()

        # Create the destination images
        cimg = cv.CloneImage(self.source_image)
        cv.Zero(cimg)
        image02 = cv.CloneImage(self.source_image)
        cv.Zero(image02)
        image04 = cv.CreateImage(cv.GetSize(self.source_image),
                                 cv.IPL_DEPTH_8U, 3)
        cv.Zero(image04)

        # Threshold the source image. This needful for cv.FindContours().
        cv.Threshold(self.source_image, image02, slider_pos, 255,
                     cv.CV_THRESH_BINARY)

        # Find all contours.
        cont = cv.FindContours(image02, stor, cv.CV_RETR_LIST,
                               cv.CV_CHAIN_APPROX_NONE, (0, 0))

        maxf = 0
        maxs = 0
        size1 = 0

        for c in contour_iterator(cont):
            if len(c) > ellipse_size:
                PointArray2D32f = cv.CreateMat(1, len(c), cv.CV_32FC2)
                for (i, (x, y)) in enumerate(c):
                    PointArray2D32f[0, i] = (x, y)

                # Draw the current contour in gray
                gray = cv.CV_RGB(100, 100, 100)
                cv.DrawContours(image04, c, gray, gray, 0, 1, 8, (0, 0))

                if iter == 0:
                    strng = segF + '/' + 'contour1.png'
                    cv.SaveImage(strng, image04)
                color = (255, 255, 255)

                (center, size, angle) = cv.FitEllipse2(PointArray2D32f)

                # Convert ellipse data from float to integer representation.
                center = (cv.Round(center[0]), cv.Round(center[1]))
                size = (cv.Round(size[0] * 0.5), cv.Round(size[1] * 0.5))

                if iter == 1:
                    if size[0] > size[1]:
                        size2 = size[0]
                    else:
                        size2 = size[1]

                    if size2 > size1:
                        size1 = size2
                        size3 = size

                # Fits ellipse to current contour.
                if eoc == 0 and iter == 2:
                    rand_val = abs((lastr - ((size[0] + size[1]) / 2)))
                    if rand_val > 20 and float(max(size[0], size[1])) / float(
                            min(size[0], size[1])) < 1.5:
                        lastcx = center[0]
                        lastcy = center[1]
                        lastr = (size[0] + size[1]) / 2

                    if rand_val > 20 and float(max(size[0], size[1])) / float(
                            min(size[0], size[1])) < 1.4:
                        cv.Ellipse(cimg, center, size, angle, 0, 360, color, 2,
                                   cv.CV_AA, 0)
                        cv.Ellipse(source_image1, center, size, angle, 0, 360,
                                   color, 2, cv.CV_AA, 0)

                elif eoc == 1 and iter == 2:
                    (int, cntr, rad) = cv.MinEnclosingCircle(PointArray2D32f)
                    cntr = (cv.Round(cntr[0]), cv.Round(cntr[1]))
                    rad = (cv.Round(rad))
                    if maxf == 0 and maxs == 0:
                        cv.Circle(cimg, cntr, rad, color, 1, cv.CV_AA, shift=0)
                        cv.Circle(source_image1,
                                  cntr,
                                  rad,
                                  color,
                                  2,
                                  cv.CV_AA,
                                  shift=0)
                        maxf = rad
                    elif (maxf > 0 and maxs == 0) and abs(rad - maxf) > 30:
                        cv.Circle(cimg, cntr, rad, color, 2, cv.CV_AA, shift=0)
                        cv.Circle(source_image1,
                                  cntr,
                                  rad,
                                  color,
                                  2,
                                  cv.CV_AA,
                                  shift=0)
                        maxs = len(c)
        if iter == 1:
            temp3 = 2 * abs(size3[1] - size3[0])
            if (temp3 > 40):
                eoc = 1
Example #6
0
def main(argv):

    TITLE = ""
    PURPLE_RADIUS_MM = 3.46 / 2
    GROWTH_MM = 600
    RGB_Array = [(0, 255, 0), (0, 0, 255), (50, 100, 0), (255, 0, 0),
                 (0, 100, 50), (100, 50, 255)]
    GRAPHGROWTH = 1
    rescale = 1
    IMAGE_FORMAT = 'png'

    parser = argparse.ArgumentParser()
    parser.add_argument('-i', '--image', required=True, dest='i')
    parser.add_argument('-d', '--data', required=True, dest='d')
    parser.add_argument('-t', '--tsnit', dest='t')
    parser.add_argument('-r', '--rescale', dest='r')
    parser.add_argument('-m', action='store_true')
    parser.add_argument('-n', action='store_true')

    args = parser.parse_args()

    if args.i is None:
        sys.exit(1)
    else:
        OPTICIMAGE = args.i
    if args.d is None:
        sys.exit(1)
    else:
        DATAFILE = args.d
    if args.t is not None:
        fileName, extension = os.path.splitext(args.t)
        tsnitData = readData(args.t, extension)
    if args.m is True:
        GRAPHGROWTH = 0
        TITLE += 'By mic '
    else:
        GRAPHGROWTH = 1
        TITLE += 'By Percent '
    #if args.n is True:
    #GRAPHGROWTH = 1
    #TITLE += 'By Percent '
    fileName, extension = os.path.splitext(DATAFILE)
    heightData = readData(DATAFILE, extension)
    if len(heightData) is 0:
        sys.exit(2)

    regex = re.compile('^[A-Z]+[0-9]+')
    basename = os.path.basename(fileName)
    m = regex.match(basename)

    whichOIS = m.group()
    SIDE = 0
    if any(s in basename.upper().replace(" ", "_") for s in ['_OD_', ' OD ']):
        SIDE = 1
        TITLE += "Right Eye Clockwise Graph"
        XLABEL = "Start at 9'o clock"
        SAVEFILE = whichOIS + '_OD'
        STARTANG = np.pi

    elif any(s in basename.upper().replace(" ", "_")
             for s in ['_OS_', ' OS ']):
        SIDE = 2
        STARTANG = 0
        SAVEFILE = whichOIS + '_OS'
        TITLE += "Left Eye Counter-Clockwise"
        XLABEL = "Start at 3'o clock"

    if args.r is not None:
        RATIOFILE = args.r
        if SIDE is 1:
            rescale = readRatio(RATIOFILE, whichOIS, 'OD')
        else:
            rescale = readRatio(RATIOFILE, whichOIS, 'OS')

    SUPRESS_ADJUSTED = False
    if rescale is 1:
        SUPRESS_ADJUSTED = True

    GRAPH_SAVE = SAVEFILE + "_GRAPH"
    IMAGE_SAVE = SAVEFILE + "_EYE"
    CSV_SAVE = SAVEFILE + '_DATA'
    # 0 nothing, 1 right, 2 left

    if GRAPHGROWTH is 1:

        GRAPH_SAVE = GRAPH_SAVE + '_PERCENT'
        IMAGE_SAVE = IMAGE_SAVE + '_PERCENT'
        CSV_SAVE = CSV_SAVE + '_PERCENT'

    else:
        GRAPH_SAVE = GRAPH_SAVE + '_MIC'
        IMAGE_SAVE = IMAGE_SAVE + '_MIC'
        CSV_SAVE = CSV_SAVE + '_MIC'

    dataFile = (open(CSV_SAVE + '.csv', 'w'))
    imgColor = cv.LoadImage(OPTICIMAGE, cv.CV_LOAD_IMAGE_UNCHANGED)
    width, height = cv.GetSize(imgColor)

    center, purpRad = centerRadius(imgColor, 2)
    xi, yi = getContour(imgColor)
    coords = zip(xi, yi)
    PointArray2D32f = cv.CreateMat(1, len(coords), cv.CV_32FC2)
    for (i, (x, y)) in enumerate(coords):
        PointArray2D32f[0, i] = (x, y)
    #(centerCont, size, angle) = cv.FitEllipse2(PointArray2D32f)
    box2d = cv.FitEllipse2(PointArray2D32f)

    fig = plt.figure(1)
    fig.subplots_adjust(hspace=.2)

    graph1 = fig.add_subplot(2, 1, 1)
    #graph2 = fig.add_subplot(3,1,2)

    #norm =  fig.add_subplot(2,1,2)
    tsnitGraph = fig.add_subplot(2, 1, 2)

    ratio = width / float(len(heightData))
    mmperpixel = PURPLE_RADIUS_MM / purpRad
    addedDist = (GROWTH_MM / 1000. / mmperpixel)

    #dataFile.write(fmtCSVArr(np.linspace(1,360,360))+"\n")
    dataFile.write("%s,%s,%s,%s,%s\n" %
                   ('name', 'shape', 'dimensions (um)', "AUC (um)",
                    fmtCSVArr(np.linspace(1, 360, 360))))
    writeTheta = np.linspace(STARTANG * 180 / np.pi,
                             (STARTANG + 2 * np.pi) * 180 / np.pi, 361)
    #dataWriter.writerow(np.around(np.linspace(0,360,len(theta)),decimals=3))
    writeTheta = writeTheta * np.pi / 180
    writeTheta = offsetGraph(writeTheta, SIDE)

    #np.savetxt(dataFile, np.linspace(0,360,len(theta)),fmt='%.3f',delimiter='\n',newline=',')
    def graphShape(ellipBox,
                   grid,
                   ratio,
                   graph=None,
                   label="",
                   color=None,
                   flags=0):
        # 1 = image
        # 2 = circle
        # 4 = ellipse
        # 8 = other graph
        ellipse = circle = image = writeOther = False
        if (flags & 0x01) != 0:
            image = True
        if (flags & 0x02) != 0:
            ellipse = True
        if (flags & 0x04) != 0:
            circle = True
        if (flags & 0x08) != 0:
            writeOther = True

        (cent, size, angle) = ellipBox
        w, l = size
        circum = circumference(l / 2, w / 2)
        d = circum / np.pi

        excelEllipeBox = (tuple(np.divide(cent, ratio)),
                          tuple(np.round(np.divide(size, ratio))), angle)
        circBox = (tuple(np.divide(cent, ratio)),
                   tuple(np.round((d / ratio, d / ratio))), angle)

        th = np.linspace(STARTANG, STARTANG + 2 * np.pi,
                         np.round(circum / ratio * 2))

        thet, h = mkPeriod(th, circBox, grid)
        f = interpolate.interp1d(
            np.concatenate(
                (thet - 2 * np.pi, thet, thet + 2 * np.pi, thet + 4 * np.pi)),
            np.concatenate((h, h, h, h)))

        writeCircHeight = f(writeTheta)

        thet, h = mkPeriod(th, excelEllipeBox, grid)
        f = interpolate.interp1d(
            np.concatenate(
                (thet - 2 * np.pi, thet, thet + 2 * np.pi, thet + 4 * np.pi)),
            np.concatenate((h, h, h, h)))

        writeEllipHeight = f(writeTheta)

        areaCirc = circum * mmperpixel / len(writeCircHeight) * np.sum(
            writeCircHeight)
        areaEllip = circum * mmperpixel / len(writeEllipHeight) * np.sum(
            writeEllipHeight)

        r, g, b = color
        ovalR, ovalG, ovalB = 255 - r, 255 - g, 255 - b
        if image is True:
            cv.Circle(imgColor,
                      tuple(np.around(cent).astype('int')),
                      int(d / 2),
                      color=cv.RGB(r, g, b))
            cv.EllipseBox(imgColor, ellipBox, cv.RGB(ovalR, ovalG, ovalB))

        #dataWriter.writerow(np.around(circHeight,decimals=3))
        #dataWriter.writerow(np.around(ellipHeight,decimals=3))
        #np.savetxt(dataFile,circHeight,fmt='%.4f',newline=',',delimiter='\n')
        #np.savetxt(dataFile,ellipHeight,fmt='%.4f',newline=',',delimiter='\n')

        #f = interpolate.interp1d(th,circHeight-ellipHeight)
        #diffHeight = f(th)
        dataFile.write(
            "%s,%s,%.0fx%.0f,%.3f,%s\n" %
            (label, 'ellipse', l * mmperpixel * 1000, w * mmperpixel * 1000,
             areaEllip, fmtCSVArr(writeEllipHeight[1:])))
        dataFile.write(
            "%s,%s,%.0fx%.0f,%.3f,%s\n" %
            (label, 'circle', d * mmperpixel * 1000, d * mmperpixel * 1000,
             areaCirc, fmtCSVArr(writeCircHeight[1:])))
        if writeOther is True:
            tsnitGraph.plot(np.linspace(0, 360, len(writeCircHeight)),
                            writeCircHeight,
                            color=(r / 255., g / 255., b / 255.),
                            label=(label + " cir AUC " +
                                   str(round(areaCirc / 1000, 3)) + " mm^2"))
        if ellipse is True:
            #dataFile.write(label+','++','+fmtCSVArr(writeEllipHeight)+"\n")
            graph.plot(np.linspace(0, 360, len(writeEllipHeight)),
                       writeEllipHeight,
                       color=(ovalR / 255., ovalG / 255., ovalB / 255.),
                       label=(label + " ellip AUC " +
                              str(round(areaEllip / 1000, 3)) + " mm^2"))

        if circle is True:
            #dataFile.write(label+','+'%.0fx%.0f'%()+','+fmtCSVArr(writeCircHeight)+"\n")
            graph.plot(np.linspace(0, 360, len(writeCircHeight)),
                       writeCircHeight,
                       color=(r / 255., g / 255., b / 255.),
                       label=(label + " cir AUC " +
                              str(round(areaCirc / 1000, 3)) + " mm^2"))

        #norm.plot(np.linspace(0,360,len(ellipHeight)),diffHeight,  label=(label+" height diff"))

    if GRAPHGROWTH is 1:
        for i in [50, 100]:
            (cent, size, ang) = box2d
            a, b = size
            circum = circumference(a / 2, b / 2) * (1 + i / 100.)
            graphShape(mkResizeBox(circum, box2d),
                       heightData,
                       ratio * rescale,
                       graph1,
                       '%' + str(i) + ' larger',
                       color=RGB_Array.pop(),
                       flags=4)

    if GRAPHGROWTH is 0:
        for i in [1, 2]:
            (cent, size, ang) = box2d
            graphShape((cent, tuple(np.add(size, addedDist * 2 * i)), ang),
                       heightData,
                       ratio * rescale,
                       graph1,
                       str(int(i * GROWTH_MM)) + ' um',
                       color=RGB_Array.pop(),
                       flags=4)

    (cent, size, ang) = box2d
    circleBox = (tuple(center), size, ang)
    graphShape(mkResizeBox(2 * np.pi * purpRad, circleBox),
               heightData,
               ratio,
               graph1,
               color=RGB_Array.pop(),
               label=str(3.46),
               flags=15)
    if SUPRESS_ADJUSTED is False:
        graphShape(mkResizeBox(2 * np.pi * purpRad, circleBox),
                   heightData,
                   ratio * rescale,
                   graph1,
                   color=RGB_Array.pop(),
                   label='3.46 adjusted',
                   flags=15)

    cv.SaveImage(IMAGE_SAVE + '.' + IMAGE_FORMAT, imgColor)

    graph1.set_title(TITLE + '\nscaling factor: ' + str(round(rescale, 3)))
    #norm.set_title('Circle and Oval Height Difference')
    #norm.set_xlabel(XLABEL +'(Degrees)')
    #norm.legend(bbox_to_anchor=(1.13,1), prop={'size':6})

    tsnitCircum = np.pi * PURPLE_RADIUS_MM * 2 / 1000
    tsnitArea = tsnitCircum / len(tsnitData) * np.sum(tsnitData)
    tsnitGraph.plot(np.linspace(0, 360, len(tsnitData)),
                    tsnitData,
                    color=tuple(np.divide(RGB_Array.pop(), 255.)),
                    label=("3.46 TSNIT " + str(round(tsnitArea, 3)) + 'mm^2'))
    dataFile.write("%s,%s,%.0fx%.0f,%.3f,%s\n" %
                   ("tsnit", 'circle', PURPLE_RADIUS_MM * 2 * 1000,
                    PURPLE_RADIUS_MM * 2 * 1000, tsnitArea * 1000, ''))
    tsnitGraph.set_title('TSNIT GRAPH')
    tsnitGraph.set_xlabel(XLABEL + '(Degrees)')
    tsnitGraph.legend(bbox_to_anchor=(1.13, 1), prop={'size': 6})

    plt.ylabel('Heights (nm)')

    #graph.set_xlabel(XLABEL +'(Degrees)')
    graph1.legend(bbox_to_anchor=(1.13, 1), prop={'size': 6})
    #graph2.legend(bbox_to_anchor=(1.13,1),prop={'size':8})
    fontP = FontProperties()
    fontP.set_size('xx-small')

    plt.savefig(GRAPH_SAVE + "." + IMAGE_FORMAT)
    dataFile.close()