1、今天在设计按键功能时,调用Find_rec函数处理图像,出现了出现了Trigger signal, code:SIGSEGV(11)!报错,
代码如下,部分省略
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| def find_rec(img): # img = cam.read() # img.lens_corr(strength=1.7) img_rec = image.image2cv(img, False, False).copy() gray_rec = cv2.cvtColor(img_rec, cv2.COLOR_RGB2GRAY) # 边缘检测 edges = cv2.Canny(gray_rec, 150, 250) kernel = np.ones((4, 4), np.uint8) dilated = cv2.dilate(edges, kernel, iterations=1)
# 轮廓检测 contours, _ = cv2.findContours(dilated, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if len(contours) > 0: # 筛选出最大的轮廓 largest_contour = max(contours, key=cv2.contourArea) epsilon = 0.02 * cv2.arcLength(largest_contour, True) approx = cv2.approxPolyDP(largest_contour, epsilon, True) # filtered_approx = remove_duplicate_points(approx) num_vertices = len(approx)
img_show = image.cv2image(img_rec, False, False)
print("img OK")
# disp.show(img_show) return img_show
|
2、Find_rec 函数单独调用是正常使用的,放在UI里进行按键触发,就会出bug。
一开始以为图像已经被释放或修改,在多个地方print,处理后的图像传递引用img.copy副本,问题也没有解决
1 2 3
| print("img format:", img.format()) print("img size:", img.width(), img.height()) print("img type:", type(img))
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| if start_press: infoimg = image.Image(disp.width(), disp.height(), image.Format.FMT_RGB888) infoimg.draw_string( disp.width() // 2 - 80, disp.height() // 2, "EXITING...", color=iRGB(255, 0, 0), scale=2 ) # processed_img = infoimg processed_img = find_rec(img.copy()) # 传入新拷贝
if Ex_fun_press: start_press = False if processed_img: # 显示前验证 if processed_img.format() == image.Format.FMT_RGB888: print("format success") return True, processed_img.copy() # 失败时返回原始图像 print("fail") return True, img.copy()
|
3、如果不调用Find_rec函数,而是新建一张图片,是可以正常显示的
说明不是外部逻辑问题,是函数内部出了问题
1 2 3 4 5 6
| def find_rec(img): img_rec = image.image2cv(img, False, False).copy() img_show = image.cv2image(img_rec, False, False) print("img OK") return img_show
|
4、后面我删掉多余的处理函数,还是有问题
在 find_rec(img) 的最后,创建一个新的稳定图像对象,并将转换后的图像绘制到这个图像上,问题得到解决
1 2 3 4 5 6 7 8 9
| def find_rec(img): img_rec = image.image2cv(img, False, False).copy() img_show = image.cv2image(img_rec, False, False)
stable_img = image.Image(img_show.width(), img_show.height(), image.Format.FMT_RGB888) stable_img.draw_image(0, 0, img_show)
return stable_img
|
总结:为什么前面都“看着没问题但还是崩溃”
cv2image() 返回的 image.Image 实际上是 C 层快速构造的临时对象,它不像用 image.Image() 构造的那样“稳定”可控。
所以 只要任何时候用过 cv2image(),在 return 之前必须 draw_image() 到一个新图像中,确保内存托管在 Python 层。