2017-05-03 5 views
0

画像から各円の陰影値を取得したい。pythonを使用して特定の順序で円に番号を付けるにはどうすればよいですか?

  1. HoughCircleを使用して円を検出しようとしています。
  2. 私はそれぞれの円の中心を取得します。
  3. テキスト(円の番号)を円で囲みます。
  4. ピクセルサブセットを設定してシェーディング値を取得し、平均シェーディング値を計算します。
  5. サークル番号の結果、中心の座標、平均シェーディング値をCSV形式で取得したいと考えています。

しかし、第3ステップでは、円番号がランダムに割り当てられました。だから、サークル番号を見つけることはとても難しいです。

シーケンスの円に番号を付けるにはどうすればよいですか?

enter image description here

# 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() 
+0

Numbered circles

およびCSVはと始まりますか?行方向または列方向? –

+0

何でもできます。 – GeoPark

答えて

0

はあなたを並べ替えることができそのx, y値に基づいてRの円は、例えば画像の幅とラフな行の高さは、:

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ライブラリを使用する方が簡単です。この方法では、各エントリを文字列に変換し、各エントリ間にカンマを追加する必要はありません。 enumerate()は、各サークルを自動的に数えるために使用できます。また、getTextSize()を使用して、印刷するテキストの寸法を決定し、矩形にセンタリングすることができます。

次のようにこれは、あなたの出力を与える:あなたがそれらを番号を付けるにはどうすればよい

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 
+0

ありがとうございました。私の仕事には本当に役立ちます。 – GeoPark

+0

あなたは大歓迎です!上下の矢印の下にある灰色のチェックマークをクリックして、解決策を受け入れた解決策として受け入れることを忘れないでください。 –

1

あなたのコード内の間違いはあなたの番号がランダムできcv2.HoughCirclesから返さlist中の円の順序に依存しているということですので、私はこのような状況で行われたであろうことは考案することですIDに各サークルのcenter(x, y)値を変換します式、及びその中心位置を与えられた同じ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)) 
+0

ありがとうございました。 – GeoPark

関連する問題