Хорошие у меня есть этот код и я не осознаю, что я должен перемещать его параметры в функцию ни, которые возвращать.
Он возвращает мне ошибку, которой "grayFrame" он не определен. Я не понимаю, быть ли объявлять это по-другому или в другом месте.
line 41, in buscar_circulos circles = cv2. HoughCircles (grayFrame, cv2. HOUGH_GRADIENT,1,20,param1=50,param2=30,minRadius=0,maxRadius=0) NameError: ямс 'grayFrame' is not defined
Мой код
import numpy as np
import cv2
cap = cv2.VideoCapture(1)
# Función main
def main():
cv2.namedWindow('ventana')
cv2.setMouseCallback('ventana',buscar_circulos)
while(True):
ret, frame = cap.read()
grayFrame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
grayFrame = cv2.medianBlur(grayFrame,5)
cv2.imshow('ventana',grayFrame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
def buscar_circulos(event,x,y,flags,param):
if event == cv2.EVENT_LBUTTONDOWN:
circles = cv2.HoughCircles(grayFrame,cv2.HOUGH_GRADIENT,1,20,param1=50,param2=30,minRadius=0,maxRadius=0)
if circles is not None:
circles = np.round(circles[0, :]).astype(int)
for (x, y, r) in circles:
cv2.circle(grayFrame, (x, y), r, (255, 0, 0), 1)
print (x,y)
if __name__ == '__main__':
main()
Для этого, deberГ-схвати использовать глобальные переменные, Г©stas они идут despuГ©s import и могут называться в cГіdigo как будто переменной mГЎs он был, в отличие от которого, чтобы менять ему стоимость, нужно использовать размещенное слово global
.
Ты cГіdigo quedarГ - в asГ-:
import numpy as np
import cv2
grayFrame = ""
cap = cv2.VideoCapture(1)
def main():
global grayFrame #Con esto ya puedes modificar su valor en este método
cv2.namedWindow('ventana')
cv2.setMouseCallback('ventana',buscar_circulos)
while(True):
ret, frame = cap.read()
grayFrame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
grayFrame = cv2.medianBlur(grayFrame,5)
cv2.imshow('ventana',grayFrame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
def buscar_circulos(event,x,y,flags,param):
if event == cv2.EVENT_LBUTTONDOWN:
circles = cv2.HoughCircles(grayFrame,cv2.HOUGH_GRADIENT,1,20,param1=50,param2=30,minRadius=0,maxRadius=0)
if circles is not None:
circles = np.round(circles[0, :]).astype(int)
for (x, y, r) in circles:
cv2.circle(grayFrame, (x, y), r, (255, 0, 0), 1)
print (x,y)
if __name__ == '__main__':
main()
Как хорошо показывает пользователь @Saelyth в комментариях этой publicaciГіn, нужно быть осторожно с глобальными переменными, aquГ - мотив:
https://stackoverflow.com / questions / 19158339/why-are-global-variables-evil
Другая альтернатива в подсказку @XBoss serГ, - чтобы герметизировать в корпусе все в классе и определять параметр в Вашем "стартапе", этот параметр может быть использованным всеми функциями внутри класса.
import numpy as np
import cv2
cap = cv2.VideoCapture(1)
class MiProgramita(object):
"""Esta clase sirve para [inserta como funciona]"""
def __init__(self):
"""Define variables que se inicializan a nivel de clase"""
self.grayframe = ""
def main(self):
"""Código principal"""
cv2.namedWindow('ventana')
cv2.setMouseCallback('ventana',buscar_circulos)
while(True):
ret, frame = cap.read()
self.grayFrame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
self.grayFrame = cv2.medianBlur(self.grayFrame, 5)
cv2.imshow('ventana', self.grayFrame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
def buscar_circulos(self, event,x,y,flags,param):
"""Función que busca circulos"""
if event == cv2.EVENT_LBUTTONDOWN:
circles = cv2.HoughCircles(self.grayFrame,cv2.HOUGH_GRADIENT,1,20,param1=50,param2=30,minRadius=0,maxRadius=0)
if circles is not None:
circles = np.round(circles[0, :]).astype(int)
for (x, y, r) in circles:
cv2.circle(self.grayFrame, (x, y), r, (255, 0, 0), 1)
print (x,y)
if __name__ == '__main__':
ClaseInstanciada = MiProgramita() # Inicializa la clase
ClaseInstanciada.main() # Llama a la función main de la clase.
, В случае когда ты не понимай, поскольку функционирует эта, soluciГіn, tendrГ-схвати, что читать на cГіmo функционируют Class в Пайтоне (Или в programaciГіn ориентируемая на объекты, действительно).
Ни существует третья одна vГ - чтобы для это делать без необходимости использовать глобальные переменные ни включать это в классе; переходит с callback vГ - в аргументы все то, в чем он нуждается. Мы можем перемещать словарь с ключом "grayFrame", и который это считал стоимостью array (frame). В существо словарь mutable, мы можем изменять это с обеих функций (в Пайтоне аргументы проходят из-за asignaciГіn). Могут проходить аргументы, которые давайте хотеть используя словарь или другой объект mutable как список, DataClass, и т.д. В C ++ podrГ-хозяева использовать struct, например.
В этот случай setMouseCallback
помещает в нашу disposiciГіn аргумент param
(userdata
в C ++), что существует для этого точно:
import numpy as np
import cv2
# Función main
def main():
cap = cv2.VideoCapture(1)
params = {"grayFrame": None}
cv2.namedWindow('ventana')
cv2.setMouseCallback('ventana', buscar_circulos, param=params)
while True:
ret, frame = cap.read()
grayFrame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
grayFrame = cv2.medianBlur(grayFrame, 5)
params["grayFrame"] = grayFrame
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.imshow('ventana', params["grayFrame"])
cap.release()
cv2.destroyAllWindows()
def buscar_circulos(event, x, y, flags, param):
if event == cv2.EVENT_LBUTTONDOWN:
grayFrame = param["grayFrame"]
circles = cv2.HoughCircles(grayFrame, cv2.HOUGH_GRADIENT, 1, 20,
param1=50, param2=30, minRadius=0, maxRadius=0
)
if circles is not None:
circles = np.round(circles[0, :]).astype(int)
for x, y, r in circles:
cv2.circle(grayframe, (x, y), r, (255, 0, 0), 1)
print(x, y)
if __name__ == '__main__':
main()
С grayFrame = param["grayFrame"]
мы способствуем тому, чтобы переменная grayFrame
указала на ссылку объекта, в который он указывает на в этом моменте ключ "grayFrame"
. Это помимо позволения писать меньше cГіdigo предотвращает ее bГєsqueda в словаре каждый раз, когда мы нуждаемся в стоимости, тем не менее, если мы будем распределять новый объект, нужно делать посредством param["grayFrame"] = obj
, если распределяется grayFrame
только, изменяется эта локальная переменная, не param["grayFrame"]
и следовательно он не влияет на main()
. Помнить каждый раз, когда переменные в одиноком Пайтоне отождествляющие снабжает ссылками объект в памяти.
не, если ты cГіdigo оно будет функционировать, как я думаю, что ты ждешь, она detecciГіn только tendrГЎ место в frame (когда кликают) и только dibujarГЎn они cГ-rculos в этом frame в течение мгновения. Если то, что ты хочешь, состоит в том, чтобы включать или дезактивировать ее detecciГіn, когда левша кликать, ты можешь использовать флаг и реализовывать ее detecciГіn mainloop:
import numpy as np
import cv2
def buscar_circulos(event, x, y, flags, param):
if event == cv2.EVENT_LBUTTONDOWN:
param["buscar"] = not(param["buscar"])
def main():
cap = cv2.VideoCapture(0) # Cambiar dispositivo si procede
params = {"buscar": False}
cv2.namedWindow('ventana')
cv2.setMouseCallback('ventana', buscar_circulos, param=params)
while True:
ret, frame = cap.read()
if params["buscar"]:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray,(9, 9), 2, 2);
circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 75,
param1=100, param2=50,
minRadius=0, maxRadius=0
)
if circles is not None:
circles = np.round(circles[0, :]).astype("int")
for (x, y, r) in circles:
cv2.circle(frame, (x, y), r, (0, 255, 0), 4)
cv2.rectangle(frame, (x - 5, y - 5), (x + 5, y + 5), (0, 128, 255), -1)
cv2.imshow('ventana', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
main()
, кликнув в окне, включает ее detecciГіn, вновь кликнув, он дезактивируется и asГ - последовательно. Предварительный фильтр и они parГЎmetros HoughCircles
deberГЎn быть отделанными для каждого особенного случая.