简体   繁体   English

如何使用python按特定顺序编号圆圈?

[英]How can I number circles in a certain order using python?

I want to get the shade value of each circles from an image. 我想从图像中获取每个圆圈的阴影值。

  1. I try to detect circles using HoughCircle . 我尝试使用HoughCircle检测圆。
  2. I get the center of each circle. 我得到每个圆的中心。
  3. I put the text (the circle numbers) in a circle. 我将文本(圆圈数字)围成一圈。
  4. I set the pixel subset to obtain the shading values and calculate the averaged shading values. 我设置像素子集以获得阴影值并计算平均阴影值。
  5. I want to get the results of circle number, the coordinates of the center, and averaged shading values in CSV format. 我想获取CSV格式的圈数,中心坐标和平均着色值的结果。

But, in the 3rd step, the circle numbers were randomly assigned. 但是,在第三步中,圈号是随机分配的。 So, it's so hard to find circle number. 因此,很难找到圈号。

How can I number circles in a sequence? 如何按顺序编号圆圈?

在此处输入图片说明

# USAGE
# python detect_circles.py --image images/simple.png

# import the necessary packages
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
circles_values=open('circles_value.csv', 'w')

# 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.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")


number=1
font = cv2.FONT_HERSHEY_SIMPLEX

# loop over the (x, y) coordinates and radius of the circles
for (x, y, r) in circles:
    # draw the circle in the output image, then draw a rectangle
    # corresponding to the center of the circle
    number=str(number)
    cv2.circle(output, (x, y), r, (0, 255, 0), 4)
    cv2.rectangle(output, (x - 10, y - 10), (x + 10, y + 10), (0, 128, 255), -1)
    # number each circle, but its result shows irregular pattern 
    cv2.putText(output, number, (x,y), font,0.5,(0,0,0),2,cv2.LINE_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
    circles_values.write(number+','+str(x)+','+str(y)+','+str(sample_average_value)+'\n')
    number=int(number)
    number+=1

# show the output image
cv2.namedWindow("image", cv2.WINDOW_NORMAL)
cv2.imshow("image", output)
cv2.waitKey(0)

# close the csv file
circles_values.close()

The mistake in your code is that your number is dependent upon the order of circles in list returned from cv2.HoughCircles which can be random, So what I would have done in this situation is to devise a formula which would convert the center(x, y) value of each circle to an ID, and the same circle would yield same ID given its center position remains same: 您代码中的错误是您的数字取决于cv2.HoughCircles list返回的list的圆圈顺序,它可以是随机的,因此在这种情况下,我要做的是设计一个公式来转换center(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))

You could sort your circles based on their x, y values, the width of the image and a rough line height, for example: 您可以根据圆的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)

Also, it is easier to use Python's CSV library to write entries to your output file. 同样,使用Python的CSV库将条目写入输出文件也更容易。 This way you don't need to convert each entry to a string and add commas between each entry. 这样,您无需将每个条目转换为字符串并在每个条目之间添加逗号。 enumerate() can be used to count each circle automatically. enumerate()可用于自动计数每个圆。 Also getTextSize() can be used to determine the dimensions of the text to be printed enabling you to centre it in the rectangle. getTextSize()也可用于确定要打印的文本的尺寸,使您可以将其居中放置在矩形中。

This would give you an output as follows: 这将为您提供如下输出:

编号的圆圈

And a CSV starting as: CSV开头为:

1,2,29,nan
2,51,19,nan
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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用 python 将圆形拟合成一个形状? - How can I fit circles into a shape using python? 如何正确分类图像中正(亮)圈和负(暗)圈的数量 - How can I correctly classify the number of positive (bright color) circles and negative (dark color) circles in the image 如何使用Python找到一定范围内每个偶数的总和? - How can I find the sum of every even number in a certain range using Python? 如何计算python中一定范围内不为零的行数? - How can I count the number of rows that are not zero in a certain range in python? 如何使用 python - timedelta 在日期中添加特定天数? - How can I add certain number of day to a date, with python - timedelta? 在Python中,如何识别重叠的圆团? - In Python, how can I identify clusters of overlapping circles? 为什么我不能在 Python 上单击和拖动圆圈? - why can i not click and drag circles on Python? 如何在Linux上更改Python上的默认版本以安装和使用某些模块? - How can I change the default version on Python on linux in order to install and use certain modules? 如何编写while循环以使其在2个变量获得某些值时停止? (Python) - How can I write while loop in order to make it stop when 2 variables got certain values? (Python) 如何在 Python 中使用 bnlearn 订购推理结果? - How can I order an inference result using bnlearn in Python?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM