【发布时间】:2018-05-05 04:04:29
【问题描述】:
我在Raspberry pi 上运行python3.6 和openCV(操作系统为Raspbian)
代码大致结构如下。
image以时间间隔(3~5 分钟)捕获。捕获的
image在函数中处理并返回测量值(精度类型)- 迭代 1.~2。直到
end_check()返回True
问题是最近拍摄的image 已过期。看起来它是在大约 10 分钟前拍摄的。最近拍摄的所有图像都迟到了。但是开头拍摄的images 似乎是定时的。并且正确输入的所有.jpg文件中记录的时间
+看起来这个问题是在一个多小时后发生的。 (20~22 次迭代)
Images 在cv2 包中被cam0.read() 捕获。以下是代码的主要部分。上传完整代码很长。有人要求,我会更新。
def run(interval,model_list):
cam0 = cv2.VideoCapture(0) #Only cam0 is used. cam2 is just to record.
camdir = "/home/pi/capstone/cam0/"
cam2 = cv2.VideoCapture(1)
cam2dir = "/home/pi/capstone/cam2/"
runNo = 0
acc_list = list()
error_list = list()
end = False
while(end == False):
print(runNo,"th run")
img_name = "%s.jpg" %runNo
frame, res = cam0.read() #`res` is the image which will be processed
cv2.imwrite(os.path.join(camdir,img_name),res)
_ , cam2pic = cam2.read()
cv2.imwrite(os.path.join(cam2dir,img_name),cam2pic)
try:
temp = Real(res)
mat = temp.match(model_list)
acc_list.append([mat,runNo])
print("Accuracy=", mat)
except ValueError:
acc_list.append(["ValueError",runNo])
error_list.append(["ValueError",runNo])
except AttributeError:
acc_list.append(["AttributeError", runNo])
error_list.append(["AttributeError",runNo])
except SmallObjectError:
acc_list.append(["SmallObjectError", runNo])
error_list.append(["SmallObjectError",runNo])
runNo = runNo+1
endNo = 40
if(runNo/2 > endNo):
end_check(res, end)
elif(runNo > endNo):
end = True
sleep(interval*60)
with open("acc_list.txt", "w") as output: #records for tracking errors
output.write(str(acc_list))
with open("err_list.txt", "w") as output:
output.write(str(error_list))
cam0.release()
cam2.release()
run(3.5,model_list)
(+) 一些新发现的东西和猜测
- 随着代码的运行,
images的时间差距越来越大 - 代码终于显示
OpenCV Error - 看起来有点像
Video signal存储在 RAM 中的R-pi和.read()返回过时的image在RAM - 将
Video signal存储在RAM中引发资源问题
下面是OpenCV Error
OpenCV Error: Assertion failed (dsize.area() > 0 || (inv_scale_x > 0 && inv_scale_y > 0)) in resize, file /home/pi/opencv/opencv-3.4.0/modules/imgproc/src/resize.cpp, line 4045
Traceback (most recent call last):
File "runpi.py", line 264, in <module>
run(3.5,model_list)
File "runpi.py", line 234, in run
mat = temp.match(model_list)
File "runpi.py", line 184, in match
self.__resize(model.get_m_inform())
File "runpi.py", line 147, in __resize
self.mask = cv2.resize(self.mask, None, fx=reratio, fy=reratio, interpolation = inter_method)
cv2.error: /home/pi/opencv/opencv-3.4.0/modules/imgproc/src/resize.cpp:4045: error: (-215) dsize.area() > 0 || (inv_scale_x > 0 && inv_scale_y > 0) in function resize
(+) 部分代码引发错误
这是__.resize() 方法。当我手动处理OpenCV Error 发生的image 时,即使OpenCV Error 指出image 的大小很重要,它也能正常工作。所以我认为这与image 本身或size 从md_inf() 获得无关。无论如何,这是代码。
def __resize(self, md_inf):
#md_inf = [219, 122, 132, 171, 262] <-sample
reratio = md_inf[0]/self.y
if(reratio>1):
inter_method = cv2.INTER_LINEAR
else:
inter_method = cv2.INTER_AREA
###below is line 147###
self.mask = cv2.resize(self.mask, None, fx=reratio, fy=reratio, interpolation = inter_method)
temp = np.zeros((md_inf[3], md_inf[4]), np.uint8)
m_cx, m_cy = md_inf[1:3]
_, contour, _ = cv2.findContours(self.mask, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
total_contour = contour[0]
for ctr in contour[1:]:
total_contour = np.concatenate((total_contour, ctr), axis =0)
mmt = cv2.moments(total_contour)
if(mmt['m00'] < 7500):
raise SmallObjectError
self.cy = int(mmt['m10']/mmt['m00']) #y is horrizon axis
self.cx = int(mmt['m01']/mmt['m00']) #x is vertical axis
x, y = self.mask.shape
adjust = m_cx - self.cx + x - temp.shape[0]
if(adjust > 0):
m_cx = m_cx - adjust
temp[(m_cx-self.cx):(m_cx-self.cx) +x, (m_cy-self.cy):(m_cy-self.cy) +y] = self.mask
self.mask = temp
【问题讨论】:
-
我怀疑你是“遭受缓冲”。我认为从相机读取的视频数据是缓冲的,如果你不经常读取它,你可能会得到一直在缓冲区中的旧数据。一种解决方案可能是在开始时设置较低的帧速率。另一个可能是启动第二个线程/进程,该线程/进程连续将相机中的图像循环读取到 4 个内存缓冲区中,当你想要一帧时,你只需复制另一个线程填充的最后一个,这样如果你读到 8每秒帧数,最旧的帧永远不会超过 1/2 秒。
-
@MarkSetchell 非常感谢。我可以为这两种解决方案获得一些参考吗?
-
我在您粘贴的代码中没有看到任何
imread... -
@DanMašek 哦,你是对的。这是一个很大的错误。
-
@DanMašek 更新了代码,而
match并不是真正有用。所以跳过了。谢谢大家指点
标签: image opencv raspberry-pi