Stack Overflow en español Asked by Sheccid Selene Cortés Servín on December 31, 2020
Estoy intentando encontrar el centroide de una área de un contorno que marqué con un rectángulo pero cuando añado la parte con los momentos me aparece un error ZeroDivisionError: float division by zero
y dado a eso no me marca el centroide en cada uno de los contornos.
Estoy agregando un for
dentro del for
que esta colocando los rectángulos del área encontrada y lo coloco ahí porque ya que se iteró en dibujar el rectángulo de las áreas, quiero que ahora itere para poner el centroide en cada uno de ellos.
from matplotlib import pyplot as plt
import cv2
import numpy as np
image = cv2.imread('radio.jpg',0)
img = cv2.resize(image,(600,300))
ret,th1 = cv2.threshold(img,49,255,cv2.THRESH_BINARY)
im_flood_fill_inv = cv2.bitwise_not(th1)
imgr = cv2.threshold(im_flood_fill_inv,49,255, cv2.THRESH_BINARY)[1]
num_labels, labels_im = cv2.connectedComponents(imgr)
def imshow_components(labels):
label_hue = np.uint8(179*labels/np.max(labels))
blank_ch = 255*np.ones_like(label_hue)
labeled_img = cv2.merge([label_hue, blank_ch, blank_ch])
labeled_img = cv2.cvtColor(labeled_img, cv2.COLOR_HSV2BGR)
labeled_img[label_hue==0] = 0
cv2.imshow('labeled',labeled_img)
ret,th1 = cv2.threshold(labeled_img,49,255,cv2.THRESH_BINARY)
histo = cv2.calcHist([th1],[0],None,[256],[0,256])
plt.hist(th1.ravel(),256,[0,256]); plt.show()
contours, _ = cv2.findContours(th1, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img, contours, -1, (0, 0, 255), 2, cv2.LINE_AA)
lista = []
for c in contours:
area = cv2.contourArea(c)
if area > 1000 and area < 10000:
cv2.drawContours(img, [c], 0, (0, 255, 0), 2, cv2.LINE_AA)
lista.append(area)
resultado = sorted(lista, reverse=True)[0:-2]
print("Áreas encontradas:", resultado)
for c in contours:
area = cv2.contourArea(c)
if area > 1300 and area < 10000:
(x, y, w, h) = cv2.boundingRect(c)
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 1, cv2.LINE_AA)
for i in contours:
momentos = cv2.moments(i)
cx = int(momentos['m10']/momentos['m00'])
cy = int(momentos['m01']/momentos['m00'])
cv2.circle(img,(cx, cy), 3, (0,255,0), -1)
cv2.imshow('contornos', img)
imshow_components(labels_im)
cv2.waitKey(0)
cv2.destroyAllWindows()
Estoy intentando lo recomendado por @Abulafia y esta en lo correcto. Solo que estoy imprimiendo el circulo en la esquina inferior izquierda y si intendo poner cada termino dividido entre 2 me aparece un error, ¿cómo podria colocar el circulo en el centro?
for c in contours:
area = cv2.contourArea(c)
if area > 1300 and area < 10000:
(x, y, w, h) = cv2.boundingRect(c)
rectangle= cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 1, cv2.LINE_AA)
#Momento
cv2.circle(img,(x + w, y + h),3, (0,255,0), -1)
SOLUCIÓN
Como lo comentó @Abulafia la manera adecuada de encontrár el centro de un cuadrado es tomando el promedio del ancho y altura ya que simplemente es un rectángulo.
Lo único que se hizo fue dividir el ancho y el alto entre 2 para que tome la mitad del alto y ancho del rectángulo.
for c in contours:
area = cv2.contourArea(c)
if area > 1300 and area < 10000:
(x, y, w, h) = cv2.boundingRect(c)
box = cv2.minAreaRect(c)
rectangle= cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 1, cv2.LINE_AA)
cv2.circle(rectangle,((x+(w//2)), (y+(h//2))),5 , (255,255,255),-1)
Answered by Sheccid Selene Cortés Servín on December 31, 2020
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP