如何在 opencv-python 的单独图像中 select ROI?
How can I select ROI in a separate image in opencv-python?
我正在使用 python 2.7.13 和 opencv 3.4.0。
我有一个带有 2 个绿点的视频流。我正在使用颜色检测来跟踪它们。我需要 select 两个 ROI(感兴趣区域),每个 ROI 将包含一个点,在两个单独的图像中进行进一步处理。
我编写了一个程序来检测它们并创建 ROI,但问题是它 select 只有一个区域,而有两个点。
另外,它给我错误:
“第 47 行,在
cv2.imshow ("area1",area1)
NameError: 名称 'area1' 未定义"
但是,如果我用 img=cv2.imread("image.jpg") 替换 img=frame.array 行,那么它可以工作,但只适用于图片。
Here how program works now
import cv2
import numpy as np
from picamera.array import PiRGBArray
from picamera import PiCamera
import time
import sys
lowerBound=np.array([33,80,40])
upperBound=np.array([102,255,255]) #ranges for green color
camera = PiCamera()
camera.rotation = 180
camera.resolution = (320, 240)
camera.framerate = 30
font=cv2.FONT_HERSHEY_SIMPLEX
rawCapture = PiRGBArray(camera, size=(320, 240))
time.sleep(0.1)
kernelOpen=np.ones((5,5))
kernelClose=np.ones((20,20))
for frame in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True): # capture frames from the camera
img = frame.array #works only if I change this with img =cv2.imread("image.jpg")
imgHSV= cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
mask=cv2.inRange(imgHSV,lowerBound,upperBound)
maskOpen=cv2.morphologyEx(mask,cv2.MORPH_OPEN,kernelOpen)
maskClose=cv2.morphologyEx(maskOpen,cv2.MORPH_CLOSE,kernelClose) #apply morphology for greater accuracy
maskFinal=maskClose
_, conts, _=cv2.findContours(maskFinal.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
for i in range(len(conts)):
x,y,w,h=cv2.boundingRect(conts[i])
area1=img[y:y+h, x:x+w] #selecting my ROI
cv2.rectangle(img,(x,y),(x+w,y+h),(0,0,255), 2)
cv2.imshow("maskClose",maskClose)
cv2.imshow("maskOpen",maskOpen)
cv2.imshow("mask",mask)
cv2.imshow("cam",img)
cv2.imshow ("area1",area1) #Showing my ROI
key = cv2.waitKey(1) & 0xFF
rawCapture.truncate(0)
if key == ord("q"):
break
在 for 循环中,您保留 setting/overwriting area1
,因此输出将始终只有一张图像。您可以通过将 imshow() 移动到 for 循环中轻松解决此问题。
在您的代码顶部添加:
prevNrOfContours = 0
使用以下代码更改帧循环:
# create a window for each roi
nrOfContours = len(conts)
for i in range(nrOfContours):
x,y,w,h=cv2.boundingRect(conts[i])
area=img[y:y+h, x:x+w] #selecting my ROI
cv2.rectangle(img,(x,y),(x+w,y+h),(0,0,255), 2)
cv2.imshow("area" + str(i), area)
# if there are more open windows then roi's
# then close the windows that will not be refreshed
if prevNrOfContours > nrOfContours:
for i in range(nrOfContours, prevNrOfContours):
cv2.destroyWindow("area" + str(i))
# store the number of roi's in this frame, so it can
# be used in the next frame
prevNrOfContours = nrOfContours
编辑:扩展代码以删除不必要的已打开 windows
Edit2:仅 select 2 个最大的轮廓:
# instantiate list
contour_list = []
for cnt in contours:
# get contour size
area = cv2.contourArea(cnt)
# add tuple of the contour and its size to the list
contour_list.append((cnt, area))
# sort list on size
sorted_list = sorted(contour_list, key=lambda x: x[1])
# create a window for the 2 largest contours
for i in range(-2,0):
x,y,w,h=cv2.boundingRect(sorted_list[i][0])
roi=img[y:y+h, x:x+w] #selecting my ROI
cv2.rectangle(img,(x,y),(x+w,y+h),(0,0,255), 2)
cv2.imshow("area" + str(i), roi)
我正在使用 python 2.7.13 和 opencv 3.4.0。 我有一个带有 2 个绿点的视频流。我正在使用颜色检测来跟踪它们。我需要 select 两个 ROI(感兴趣区域),每个 ROI 将包含一个点,在两个单独的图像中进行进一步处理。 我编写了一个程序来检测它们并创建 ROI,但问题是它 select 只有一个区域,而有两个点。 另外,它给我错误: “第 47 行,在 cv2.imshow ("area1",area1) NameError: 名称 'area1' 未定义"
但是,如果我用 img=cv2.imread("image.jpg") 替换 img=frame.array 行,那么它可以工作,但只适用于图片。 Here how program works now
import cv2
import numpy as np
from picamera.array import PiRGBArray
from picamera import PiCamera
import time
import sys
lowerBound=np.array([33,80,40])
upperBound=np.array([102,255,255]) #ranges for green color
camera = PiCamera()
camera.rotation = 180
camera.resolution = (320, 240)
camera.framerate = 30
font=cv2.FONT_HERSHEY_SIMPLEX
rawCapture = PiRGBArray(camera, size=(320, 240))
time.sleep(0.1)
kernelOpen=np.ones((5,5))
kernelClose=np.ones((20,20))
for frame in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True): # capture frames from the camera
img = frame.array #works only if I change this with img =cv2.imread("image.jpg")
imgHSV= cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
mask=cv2.inRange(imgHSV,lowerBound,upperBound)
maskOpen=cv2.morphologyEx(mask,cv2.MORPH_OPEN,kernelOpen)
maskClose=cv2.morphologyEx(maskOpen,cv2.MORPH_CLOSE,kernelClose) #apply morphology for greater accuracy
maskFinal=maskClose
_, conts, _=cv2.findContours(maskFinal.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
for i in range(len(conts)):
x,y,w,h=cv2.boundingRect(conts[i])
area1=img[y:y+h, x:x+w] #selecting my ROI
cv2.rectangle(img,(x,y),(x+w,y+h),(0,0,255), 2)
cv2.imshow("maskClose",maskClose)
cv2.imshow("maskOpen",maskOpen)
cv2.imshow("mask",mask)
cv2.imshow("cam",img)
cv2.imshow ("area1",area1) #Showing my ROI
key = cv2.waitKey(1) & 0xFF
rawCapture.truncate(0)
if key == ord("q"):
break
在 for 循环中,您保留 setting/overwriting area1
,因此输出将始终只有一张图像。您可以通过将 imshow() 移动到 for 循环中轻松解决此问题。
在您的代码顶部添加:
prevNrOfContours = 0
使用以下代码更改帧循环:
# create a window for each roi
nrOfContours = len(conts)
for i in range(nrOfContours):
x,y,w,h=cv2.boundingRect(conts[i])
area=img[y:y+h, x:x+w] #selecting my ROI
cv2.rectangle(img,(x,y),(x+w,y+h),(0,0,255), 2)
cv2.imshow("area" + str(i), area)
# if there are more open windows then roi's
# then close the windows that will not be refreshed
if prevNrOfContours > nrOfContours:
for i in range(nrOfContours, prevNrOfContours):
cv2.destroyWindow("area" + str(i))
# store the number of roi's in this frame, so it can
# be used in the next frame
prevNrOfContours = nrOfContours
编辑:扩展代码以删除不必要的已打开 windows
Edit2:仅 select 2 个最大的轮廓:
# instantiate list
contour_list = []
for cnt in contours:
# get contour size
area = cv2.contourArea(cnt)
# add tuple of the contour and its size to the list
contour_list.append((cnt, area))
# sort list on size
sorted_list = sorted(contour_list, key=lambda x: x[1])
# create a window for the 2 largest contours
for i in range(-2,0):
x,y,w,h=cv2.boundingRect(sorted_list[i][0])
roi=img[y:y+h, x:x+w] #selecting my ROI
cv2.rectangle(img,(x,y),(x+w,y+h),(0,0,255), 2)
cv2.imshow("area" + str(i), roi)