OpenCV HoughCircles调用报错及cvtColor转换错误求解
第一个报错分析与解决
Error : 'Traceback (most recent call last): File "F:\TIPE ENTROPIE\Programmation\Iris-Recognition-master\Iris Code\norm.py", line 82, in
extract_iris(img) File "F:\TIPE ENTROPIE\Programmation\Iris-Recognition-master\Iris Code\norm.py", line 53, in extract_iris cord = get_circle(img, 35, 0, 50, 40) File "F:\TIPE ENTROPIE\Programmation\Iris-Recognition-master\Iris Code\norm.py", line 14, in get_circle circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT,1,20, param1=p1,param2=p2,minRadius=minR,maxRadius=maxR) cv2.error: C:\projects\opencv-python\opencv\modules\imgproc \src\hough.cpp:1494: error: (-215) !_image.empty() && _image.type() == (((0) & ((1 << 3) - 1)) + (((1)-1) << 3)) && (_image.isMat() || _image.isUMat()) in function cv::HoughCircles`
这个报错的核心是输入到HoughCircles的图像不符合要求:
!_image.empty():图像为空,大概率是cv2.imread读取失败,比如文件路径错误、目标图片不存在_image.type() == ...:图像类型不匹配,HoughCircles要求输入必须是单通道8位灰度图(CV_8UC1类型)
解决要点:
- 确保图片路径正确,建议使用绝对路径;
- 在读取图像后增加有效性校验:
img = cv2.imread('test6.jpg',0) if img is None: print("无法读取图像,请检查路径或文件是否存在") exit()
第二个报错分析与解决
Traceback (most recent call last): File "F:\TIPE ENTROPIE\Programmation\essai.py", line 80, in
extract_iris(img) File "F:\TIPE ENTROPIE\Programmation\essai.py", line 49, in extract_iris cord = get_circle(cimg, 35, 0, 50, 40) File "F:\TIPE ENTROPIE\Programmation\essai.py", line 8, in get_circle img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) cv2.error: C:\projects\opencv-python\opencv\modules\imgproc\src\color.cpp:11111: error: (-215) scn == 3 || scn == 4 in function cv::cvtColor
这个报错是因为cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)要求输入必须是**3通道(BGR)或4通道(BGRA)**图像,但你第二次调用get_circle(nimg, ...)时,nimg是灰度图(从原灰度图截取而来),此时执行颜色转换就会因为单通道输入而报错。
另外你的get_circle函数逻辑混乱:时而传入彩色图,时而传入灰度图,导致转换逻辑冲突。需要统一函数的输入处理逻辑。
完整修复后的代码
我帮你整理了修复后的代码,同时优化了边界越界、参数合理性等细节:
import cv2 import numpy as np ## Definitions def get_circle(img, minR, maxR, p1, p2): # 自动处理图像类型:如果是彩色图转灰度,灰度图直接使用 if len(img.shape) == 3: gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) else: gray = img.copy() # 调用HoughCircles,增加参数合理性校验 circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 20, param1=p1, param2=p2, minRadius=minR, maxRadius=maxR) # 检查是否检测到圆,避免后续索引报错 if circles is None: raise ValueError("未检测到符合条件的圆,请调整HoughCircles参数或检查图像质量") circles = np.uint16(np.around(circles)) # 返回第一个检测到的圆 return circles[0][0] def print_img(img, x, y, w, h): if w != 0 and h != 0: display_img = img[x:x+w, y:y+h] else: display_img = img.copy() cv2.imshow('detected circles', display_img) cv2.imwrite('app-1/1.jpg', display_img) cv2.waitKey(0) cv2.destroyAllWindows() def reject_out(img, xc, yc, r): row, col = img.shape[:2] for x in range(row): for y in range(col): res = (x - xc)**2 + (y - yc)**2 if res > r*r: img[x][y] = 0 def reject_in(img, xc, yc, r): # 增加边界判断,避免数组越界 xs = max(0, xc - r) ys = max(0, yc - r) xe = min(img.shape[0], xc + r) ye = min(img.shape[1], yc + r) for x in range(xs, xe): for y in range(ys, ye): res = (x - xc)**2 + (y - yc)**2 if res < r*r: img[x][y] = 0 def extract_iris(img): # 转换为彩色图用于绘制圆(不修改原灰度图) cimg = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) # 检测外圆(虹膜边界):修正maxRadius参数(原代码传0会导致无法检测) cord_outer = get_circle(img, 35, 50, 50, 40) # 绘制外圆和圆心 cv2.circle(cimg, (cord_outer[0], cord_outer[1]), cord_outer[2], (0,255,0), 2) cv2.circle(cimg, (cord_outer[0], cord_outer[1]), 2, (0,0,255), 3) print_img(cimg, 0, 0, 0, 0) # 截取虹膜区域,增加边界判断防止越界 x = max(0, cord_outer[1] - cord_outer[2]) y = max(0, cord_outer[0] - cord_outer[2]) w = min(2*cord_outer[2], img.shape[0] - x) h = min(2*cord_outer[2], img.shape[1] - y) nimg = img[x:x+w, y:y+h] # 去除外圆外的区域 reject_out(nimg, w//2, h//2, w//2) # 检测内圆(瞳孔边界) cord_inner = get_circle(nimg, 0, cord_outer[2]-1, 50, 30) # 转换为彩色图再绘制,避免灰度图上彩色不显示的问题 nimg_color = cv2.cvtColor(nimg, cv2.COLOR_GRAY2BGR) cv2.circle(nimg_color, (cord_inner[0], cord_inner[1]), cord_inner[2], (0,255,0), 2) cv2.circle(nimg_color, (cord_inner[0], cord_inner[1]), 2, (0,0,255), 3) # 去除内圆内的区域 reject_in(nimg, cord_inner[1], cord_inner[0], cord_inner[2]) print_img(nimg_color, 0, 0, 0, 0) # 主程序入口 if __name__ == "__main__": # 读取灰度图 img = cv2.imread('test6.jpg', 0) # 检查图像读取是否成功 if img is None: print("错误:无法读取图像,请检查文件路径是否正确") exit() img = cv2.medianBlur(img, 5) extract_iris(img)
关键修复点:
- 增加图像读取有效性校验,避免空图像传入后续流程;
- 优化
get_circle函数,自动适配彩色/灰度输入,避免颜色转换报错; - 修正HoughCircles的
maxRadius参数(原代码传0会导致无法检测到圆); - 增加边界判断,防止图像截取和像素遍历时的数组越界问题;
- 调整绘制逻辑,在灰度图上绘制时先转为彩色图,确保绘制内容可见。
内容的提问来源于stack exchange,提问作者Jack




