如何使用python按特定顺序对圆进行编号?

如何使用python按特定顺序对圆进行编号?,python,opencv,numbers,circleimage,Python,Opencv,Numbers,Circleimage,我想从图像中得到每个圆的阴影值 我尝试使用houghcirle检测圆 我得到每个圆的中心 我把文字(圆圈数字)放在一个圆圈里 我设置像素子集以获得着色值并计算平均着色值 我想以CSV格式获得圆编号、中心坐标和平均着色值的结果 但是,在第三步中,圆圈编号是随机分配的。所以,很难找到圈数 如何按顺序对圆进行编号 代码中的错误是,您的数字取决于从cv2返回的list中圆圈的顺序。HoughCircles可以是随机的,因此在这种情况下,我要做的是设计一个公式,将每个圆圈的中心(x,y)值转换为一个ID

我想从图像中得到每个圆的阴影值

  • 我尝试使用
    houghcirle
    检测圆
  • 我得到每个圆的中心
  • 我把文字(圆圈数字)放在一个圆圈里
  • 我设置像素子集以获得着色值并计算平均着色值
  • 我想以CSV格式获得圆编号、中心坐标和平均着色值的结果 但是,在第三步中,圆圈编号是随机分配的。所以,很难找到圈数

    如何按顺序对圆进行编号


    代码中的错误是,您的数字取决于从
    cv2返回的
    list
    中圆圈的顺序。HoughCircles
    可以是随机的,因此在这种情况下,我要做的是设计一个公式,将每个圆圈的
    中心(x,y)
    值转换为一个ID,如果同一圆的中心位置保持不变,则该圆将产生相同的ID:

    def get_id_from_center(x, y):
        return x + y*50
    for (x, y, r) in circles:
        number = str(get_id_from_center(x, y))
    

    代码中的错误是,您的数字取决于从
    cv2返回的
    list
    中圆圈的顺序。HoughCircles
    可以是随机的,因此在这种情况下,我要做的是设计一个公式,将每个圆圈的
    中心(x,y)
    值转换为一个ID,如果同一圆的中心位置保持不变,则该圆将产生相同的ID:

    def get_id_from_center(x, y):
        return x + y*50
    for (x, y, r) in circles:
        number = str(get_id_from_center(x, y))
    

    您可以根据圆的
    x,y
    值、图像宽度和大致线条高度对圆进行排序,例如:

    import numpy as np
    import argparse
    import cv2
    import csv
    
    # define a funtion of ROI calculating the average value in specified sample size
    def ROI(img,x,y,sample_size):
        Each_circle=img[y-sample_size:y+sample_size, x-sample_size:x+sample_size]
        average_values=np.mean(Each_circle)
        return average_values
    
    # open the csv file named circles_value
    
    with open('circles_value.csv', 'wb') as circles_values:
        csv_output = csv.writer(circles_values)
    
        # construct the argument parser and parse the arguments
        ap = argparse.ArgumentParser()
        ap.add_argument("-i", "--image", required = True, help = "Path to the image")
        args = vars(ap.parse_args())
    
        # load the image, clone it for output, and then convert it to grayscale
        image = cv2.imread(args["image"])
        output = image.copy()
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
        # detect circles in the image
        circles = cv2.HoughCircles(gray, cv2.cv.CV_HOUGH_GRADIENT, 1.2,50, 100, 1, 1, 20, 30)
    
        # ensure at least some circles were found
        if circles is not None:
            # convert the (x, y) coordinates and radius of the circles to integers
            circles = np.round(circles[0, :]).astype("int")
    
        font = cv2.FONT_HERSHEY_SIMPLEX
        height =  40
    
        # loop over the (x, y) coordinates and radius of the circles
        for number, (x, y, r) in enumerate(sorted(circles, key=lambda v: v[0] + (v[1] / height) * image.shape[1]), start=1):
            text = str(number)
            (tw, th), bl = cv2.getTextSize(text, font, 0.5, 2)      # So the text can be centred in the circle
            tw /= 2
            th = th / 2 + 2
    
            # draw the circle in the output image, then draw a rectangle
            # corresponding to the center of the circle
            cv2.circle(output, (x, y), r, (0, 255, 0), 3)
            cv2.rectangle(output, (x - tw, y - th), (x + tw, y + th), (0, 128, 255), -1)
            # number each circle, centred in the rectangle
            cv2.putText(output, text, (x-tw, y + bl), font, 0.5, (0,0,0), 2, cv2.CV_AA)
            # get the average value in specified sample size (20 x 20)
            sample_average_value = ROI(output, x, y, 20)
            # write the csv file with number, (x,y), and average pixel value
            csv_output.writerow([number, x, y, sample_average_value])
    
        # show the output image
        cv2.namedWindow("image", cv2.WINDOW_NORMAL)
        cv2.imshow("image", output)
        cv2.waitKey(0)
    
    此外,使用Python的CSV库将条目写入输出文件更容易。这样,您就不需要将每个条目转换为字符串并在每个条目之间添加逗号<代码>枚举()可用于自动计算每个圆。还可以使用
    getTextSize()
    确定要打印的文本的尺寸,使您能够将其置于矩形的中心

    这将为您提供如下输出:

    和一个CSV,开头为:

    1,2,29,南
    2,51,19,南
    3,107,22,100.72437499999999
    4,173,23,102.33291666666666
    5,233,26,88.244791666666671
    6,295,22,92.953541666666666
    7,358,28,142.51625000000001
    8,418,26,155.12875
    9,484,31,127.02541666666667
    10,547,25,112.57958333333333
    
    您可以根据圆的
    x,y
    值、图像宽度和大致线条高度对圆进行排序,例如:

    import numpy as np
    import argparse
    import cv2
    import csv
    
    # define a funtion of ROI calculating the average value in specified sample size
    def ROI(img,x,y,sample_size):
        Each_circle=img[y-sample_size:y+sample_size, x-sample_size:x+sample_size]
        average_values=np.mean(Each_circle)
        return average_values
    
    # open the csv file named circles_value
    
    with open('circles_value.csv', 'wb') as circles_values:
        csv_output = csv.writer(circles_values)
    
        # construct the argument parser and parse the arguments
        ap = argparse.ArgumentParser()
        ap.add_argument("-i", "--image", required = True, help = "Path to the image")
        args = vars(ap.parse_args())
    
        # load the image, clone it for output, and then convert it to grayscale
        image = cv2.imread(args["image"])
        output = image.copy()
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
        # detect circles in the image
        circles = cv2.HoughCircles(gray, cv2.cv.CV_HOUGH_GRADIENT, 1.2,50, 100, 1, 1, 20, 30)
    
        # ensure at least some circles were found
        if circles is not None:
            # convert the (x, y) coordinates and radius of the circles to integers
            circles = np.round(circles[0, :]).astype("int")
    
        font = cv2.FONT_HERSHEY_SIMPLEX
        height =  40
    
        # loop over the (x, y) coordinates and radius of the circles
        for number, (x, y, r) in enumerate(sorted(circles, key=lambda v: v[0] + (v[1] / height) * image.shape[1]), start=1):
            text = str(number)
            (tw, th), bl = cv2.getTextSize(text, font, 0.5, 2)      # So the text can be centred in the circle
            tw /= 2
            th = th / 2 + 2
    
            # draw the circle in the output image, then draw a rectangle
            # corresponding to the center of the circle
            cv2.circle(output, (x, y), r, (0, 255, 0), 3)
            cv2.rectangle(output, (x - tw, y - th), (x + tw, y + th), (0, 128, 255), -1)
            # number each circle, centred in the rectangle
            cv2.putText(output, text, (x-tw, y + bl), font, 0.5, (0,0,0), 2, cv2.CV_AA)
            # get the average value in specified sample size (20 x 20)
            sample_average_value = ROI(output, x, y, 20)
            # write the csv file with number, (x,y), and average pixel value
            csv_output.writerow([number, x, y, sample_average_value])
    
        # show the output image
        cv2.namedWindow("image", cv2.WINDOW_NORMAL)
        cv2.imshow("image", output)
        cv2.waitKey(0)
    
    此外,使用Python的CSV库将条目写入输出文件更容易。这样,您就不需要将每个条目转换为字符串并在每个条目之间添加逗号<代码>枚举()可用于自动计算每个圆。还可以使用
    getTextSize()
    确定要打印的文本的尺寸,使您能够将其置于矩形的中心

    这将为您提供如下输出:

    和一个CSV,开头为:

    1,2,29,南
    2,51,19,南
    3,107,22,100.72437499999999
    4,173,23,102.33291666666666
    5,233,26,88.244791666666671
    6,295,22,92.953541666666666
    7,358,28,142.51625000000001
    8,418,26,155.12875
    9,484,31,127.02541666666667
    10,547,25,112.57958333333333
    
    您想如何给它们编号?行还是列?什么都行。你想如何给它们编号?行还是列?什么都行。非常感谢。非常感谢。不客气!别忘了点击上/下箭头下的灰色勾号,接受答案作为已接受的解决方案。欢迎您!不要忘记单击上/下箭头下的灰色勾号,接受答案作为已接受的解决方案。