2016-08-11 2 views
5

В настоящее время я занимаюсь обнаружением круга на изображениях, похожим на этот, но некоторые из капель сливаются и образуют некоторые нерегулярные фигуры (красные метки в исходном изображении). Я использую функцию houghcircle в opencv для обнаружения кругов. Для этих нерегулярных фигур функция может обнаруживать их только как несколько небольших кругов, но я действительно хочу, чтобы программа рассматривала неправильную форму как целую большую фигуру и получала большой круг, как я рисую на своем выходном изображении.Обнаружение нерегулярных фигур с использованием функции houghcircle opencv python

Original image

Output image

Мой код будет обнаруживать все круги и получить диаметры них.

Вот мой код:

def circles(filename, p1, p2, minR, maxR): 
# print(filename) 
img = cv2.imread(filename, 0) 
img = img[0:1000, 0:1360] 
l = len(img) 
w = len(img[1]) 

cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR) 

circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 25, 
          param1 = int(p1) ,param2 = int(p2), minRadius = int(minR), maxRadius = int(maxR)) 

diameter = open(filename[:-4] + "_diamater.txt", "w") 
diameter.write("Diameters(um)\n") 
for i in circles[0,:]: 
    diameter.write(str(i[2] * 1.29 * 2) + "\n") 

count = 0 
d = [] 
area = [] 
for i in circles[0,:]: 
    cv2.circle(cimg,(i[0],i[1]),i[2],(0,255,0),2) 
    cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3) 
    count += 1 
    d += [i[2]*2] 
    area += [i[2]*i[2]*pi*1.286*1.286] 

f = filename.split("/")[-1] 
cv2.imwrite(filename[:-4] + "_circle.jpg", cimg) 

# cv2.imwrite("test3/edge.jpg", edges) 
print "Number of Circles is %d" % count 

diaM = [] 
for i in d: 
    diaM += [i*1.286] 

bWidth = range(int(min(diaM)) - 10, int(max(diaM)) + 10, 2) 

txt = ''' 
Sample name: %s 
Average diameter(um): %f  std: %f 
Drop counts: %d 
Average coverage per drop(um^2): %f  std: %f 
''' % (f, np.mean(diaM), np.std(diaM), count, np.mean(area), np.std(area)) 

fig = plt.figure() 
fig.suptitle('Histogram of Diameters', fontsize=14, fontweight='bold') 
ax1 = fig.add_axes((.1,.4,.8,.5)) 
ax1.hist(diaM, bins = bWidth) 
ax1.set_xlabel('Diameter(um)') 
ax1.set_ylabel('Frequency') 
fig.text(.1,.1,txt) 
plt.savefig(filename[:-4] + '_histogram.jpg') 
plt.clf() 

print "Total area is %d" % (w*l) 
print "Total covered area is %d" % (np.sum(area)) 

rt = "Number of Circles is " + str(count) + "\n" + "Coverage percent is " + str(np.divide(np.sum(area), (w*l))) + "\n" 
return rt 

ответ

1

Если вы все еще хотите использовать функцию HoughCircles, вы могли бы просто увидеть, если две окружности пересекаются и сделать новый круг из них.

+0

Я попытался таким образом, но есть много других кругов рядом друг с другом. Так что это не очень хорошо. Спасибо, в любом случае. –

1

Для этого можно использовать minEnclosingCircle. Найдите контуры вашего изображения, затем примените функцию для определения фигур в виде кругов.

Ниже приведен простой пример кода C++. В вашем случае я чувствую, что вы должны использовать комбинацию Hough-кругов и minEnclosingCircle, так как некоторые круги вашего изображения очень близки друг к другу, есть вероятность, что они могут быть обнаружены как один контур.

входного изображения:

input

круги:

output

Mat im = imread("circ.jpg"); 
Mat gr; 
cvtColor(im, gr, CV_BGR2GRAY); 
Mat bw; 
threshold(gr, bw, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU); 

vector<vector<Point>> contours; 
vector<Vec4i> hierarchy; 
findContours(bw, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, Point(0, 0)); 
for(int idx = 0; idx >= 0; idx = hierarchy[idx][0]) 
{ 
    Point2f center; 
    float radius; 
    minEnclosingCircle(contours[idx], center, radius); 

    circle(im, Point(center.x, center.y), radius, Scalar(0, 255, 255), 2); 
} 
0

Если у вас есть такие красивые хорошо разделенные и контрастировали узоры, проще всего было бы использовать индексы формы , См. this paper или this poster. В обоих случаях у вас есть список индексов формы.

Благодаря формированию индексов, вы можете, что следовать:

  • бинарники Образ
  • связано этикетирование компонентов, чтобы отделить каждый шаблон
  • индексов формы вычисления (большинство из них используют основные меры)
  • классифицировать шаблон в соответствии со значениями индексов формы.

Как и в вашем конкретном случае круглые формы совершенно круглые, я хотел бы использовать следующие формы индексов:

  • округлости => используя только радиусы, так что проще всего вычислить и совершенный в вашем случае.
  • Расширение/удлинение/растяжение по радиусу => Идеально подходит для вашего случая, но расчет мини-шара недоступен во всех библиотеках.
  • Iso-периметрический дефицит => очень прост в вычислении, но немного менее стабилен, чем кругооборот по периметру.

также работать в вашем случае:

  • Gap вписан диск
  • Распространение Мортон
  • Дефицита
  • Расширение диаметрами
Смежные вопросы