计算机视觉应用开发案例教程(OpenCV)习题答案汇 袁文韬 第1-9章_第1页
计算机视觉应用开发案例教程(OpenCV)习题答案汇 袁文韬 第1-9章_第2页
计算机视觉应用开发案例教程(OpenCV)习题答案汇 袁文韬 第1-9章_第3页
计算机视觉应用开发案例教程(OpenCV)习题答案汇 袁文韬 第1-9章_第4页
计算机视觉应用开发案例教程(OpenCV)习题答案汇 袁文韬 第1-9章_第5页
已阅读5页,还剩28页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第1章一、选择题答案B解析:cv2.imread()的第二个参数,0表示cv2.IMREAD_GRAYSCALE(灰度模式);A选项1表示彩色模式,C选项-1表示保留透明通道,D选项函数名错误(应为cv2.imread())。B解析:cv2.waitKey(delay)中,delay=0表示“无限等待按键”,delay>0表示“等待delay毫秒后自动继续”;A选项是cv2.waitKey(0)的错误理解,C选项是cv2.destroyAllWindows()的功能,D选项是cv2.imwrite()的功能。B/D解析:总像素数=高度×宽度×通道数,shape的顺序是(高度,宽度,通道数),因此360×640×3=691200,B和D的计算结果一致,均正确。A解析:conda创建虚拟环境的命令格式为condacreate-n环境名python=版本号;B选项缺少-n(指定环境名),C选项new是无效命令(应为create),D选项-name是长格式,虽可使用,但常用短格式-n,且题目选项中A为标准正确命令。C解析:cv2.imwrite()无法自动创建不存在的路径,若路径中的文件夹未创建,会保存失败并返回False;A、B、D均为正确说法。二、填空题答案cv2.cvtColor();cv2.COLOR_BGR2GRAY解析:cv2.cvtColor(src,code)用于通道转换,code=cv2.COLOR_BGR2GRAY表示将BGR彩色图转为灰度图。None解析:图像读取成功时返回numpy.ndarray类型数据,失败时返回None,因此判断ifimgisNone即可。cv2.destroyAllWindows();cv2.destroyWindow("GrayWindow")解析:前者关闭所有窗口,后者需指定窗口名称(与cv2.imshow()的窗口名一致)。pipinstall--upgradeopencv-python解析:--upgrade参数表示“升级已安装的库”,若需升级contrib模块,需加opencv-contrib-python。第2章一、选择题答案C解析:img.size是总像素数,彩色图像总像素数=高度×宽度×通道数(3),C选项少乘通道数,错误;A、B、D均正确。A解析:ROI切片遵循“行(高度)→列(宽度)”顺序,50:150表示行50到149(共100行),100:200表示列100到199(共100列);B选项顺序颠倒,C选项符号错误(应为:),D选项多取了0通道(B通道),均错误。B解析:cv2.split()分离彩色图像时,按“B→G→R”顺序返回通道,与OpenCV的BGR存储顺序一致;A、C顺序错误,D函数调用格式错误(无需传入通道变量)。A解析:全黑灰度图需用np.zeros()(全0),形状为(高度,宽度),100为高度、200为宽度;B选项形状颠倒,C选项用np.ones()(全1,非黑),D选项是3通道彩色图,均错误。C解析:代码将像素值大于128的设为255(白),小于等于128的设为0(黑),符合二值化定义;A、B、D均不符合代码逻辑。二、填空题答案高度;宽度;3个通道(B、G、R)解析:(h,w,3)是彩色图像的标准形状,h=height(高度),w=width(宽度),3对应B、G、R三个通道。np.stack();2解析:np.stack()可在指定维度堆叠数组,axis=2表示在第3个维度(通道维度)堆叠,将3个灰度数组转为3通道彩色数组。[0,0,255]解析:img[:,:,2]是R通道,筛选出R>200的像素后,赋值为[0,0,255](红色),符合需求。将多个单通道数组合并为多通道图像;3个单通道数组(顺序为B、G、R)解析:cv2.merge()需传入包含3个单通道数组的列表(如[b,g,r]),合并为BGR彩色图像。三、实操题答案代码示例:importcv2importnumpyasnp#1.读取彩色图像img=cv2.imread("lena.jpg",cv2.IMREAD_COLOR)ifimgisNone:print("❌图像读取失败!")else:#2.打印图像属性h,w,ch=img.shapetotal_pixels=img.sizeprint(f"图像属性:")print(f"高度:{h}像素")print(f"宽度:{w}像素")print(f"通道数:{ch}")print(f"总像素数:{total_pixels}")#3.提取中心ROI(高度100,宽度100)roi_h,roi_w=100,100#计算ROI起始坐标(居中:(总高度-ROI高度)/2,(总宽度-ROI宽度)/2)roi_y_start=(h-roi_h)//2roi_y_end=roi_y_start+roi_hroi_x_start=(w-roi_w)//2roi_x_end=roi_x_start+roi_w#提取ROIroi=img[roi_y_start:roi_y_end,roi_x_start:roi_x_end,:]print(f"ROI形状:{roi.shape}(预期:({roi_h},{roi_w},{ch}))")#4.修改ROI的G通道(索引1)为255roi[:,:,1]=255#G通道全设为255#将修改后的ROI放回原图像(直接赋值)img[roi_y_start:roi_y_end,roi_x_start:roi_x_end,:]=roi#5.标记ROI(红色矩形框)cv2.rectangle(img,(roi_x_start,roi_y_start),(roi_x_end,roi_y_end),(0,0,255),2)cv2.putText(img,"ROI(G=255)",(roi_x_start,roi_y_start-10),cv2.FONT_HERSHEY_SIMPLEX,0.6,(0,0,255),2)#6.显示与保存cv2.imshow("OriginalImage",cv2.imread("lena.jpg",cv2.IMREAD_COLOR))#原图cv2.imshow("ModifiedImage(ROIG=255)",img)#修改图cv2.imwrite("lena_roi_modified.jpg",img)print("修改后的图像已保存!")cv2.waitKey(0)cv2.destroyAllWindows()2.代码示例:importcv2importnumpyasnp#1.读取灰度图像gray_img=cv2.imread("city_gray.jpg",cv2.IMREAD_GRAYSCALE)ifgray_imgisNone:print("图像读取失败!")else:h,w=gray_img.shapeprint(f"灰度图尺寸:{h}×{w}像素")#2.方法1:for循环遍历像素反色inverted_for=gray_img.copy()#复制原图,避免修改原数据foryinrange(h):forxinrange(w):inverted_for[y,x]=255-inverted_for[y,x]print("方法1(for循环)反色完成!")#3.方法2:NumPy数组运算反色(无循环,效率高)inverted_np=255-gray_img#直接数组相减,自动广播#确保数据类型为uint8(避免溢出,NumPy会自动处理,但建议显式转换)inverted_np=inverted_np.astype(np.uint8)print("方法2(NumPy)反色完成!")#4.验证两种方法结果是否一致is_same=np.array_equal(inverted_for,inverted_np)print(f"两种方法结果是否一致?{is_same}(预期:True)")#5.显示与保存cv2.imshow("OriginalGrayImage",gray_img)cv2.imshow("Inverted(ForLoop)",inverted_for)cv2.imshow("Inverted(NumPy)",inverted_np)cv2.imwrite("city_gray_inverted.jpg",inverted_np)print("反色图已保存!")cv2.waitKey(0)cv2.destroyAllWindows()解析:方法2的NumPy数组运算无需循环,直接对整个数组操作,效率远高于for循环(尤其大图像),体现NumPy在图像处理中的优势;两种方法结果一致,验证了数组运算的正确性。第3章一、选择题答案C解析:A选项灰度化是单通道,错误;B选项灰度化需考虑人眼对绿光敏感(加权平均法),错误;D选项灰度化保留明暗细节,错误;C选项正确。B解析:自适应阈值根据局部亮度调整阈值,能解决光照不均问题;全局阈值无法处理局部明暗差异,A错误;C、D不符合实际,错误。C解析:中值滤波取区域中值,能有效消除椒盐噪声(极端值);均值和高斯滤波对椒盐噪声效果差,A、B错误;D错误。D解析:Canny的步骤是“高斯滤波→梯度计算→NMS→双阈值筛选”,无全局阈值二值化,D错误;A、B、C正确。A解析:Sobel算子中,dx=1表示计算x方向导数(检测水平边缘),dy=0表示不计算y方向,A正确;B是检测垂直边缘,C、D错误。二、填空题答案0(黑);255(白)解析:THRESH_BINARY_INV是“反二进制阈值”,与THRESH_BINARY相反,适合文本反转。ksize;sigmaX解析:高斯滤波的核心参数是滤波核大小(ksize,如(3,3))和X方向标准差(sigmaX),sigmaX越大,去噪越强。1/2~1/3;噪声(或虚假边缘)解析:低阈值过小,会将噪声误判为边缘,导致虚假边缘增多;低阈值过大,会丢失真实边缘。滤波(或去噪)解析:噪声会导致“虚假边缘”,边缘检测前先去噪(如高斯滤波),能提高边缘检测的准确性。三、实操题答案代码示例:importcv2importnumpyasnp#定义添加高斯噪声的函数(复用本章示例5)defadd_gaussian_noise(img,mean=0,var=0.005):img_float=img.astype(np.float32)/255gaussian=np.random.normal(mean,var**0.5,img.shape)img_noise=img_float+gaussianimg_noise=np.clip(img_noise,0,1)*255returnimg_noise.astype(np.uint8)#1.读取灰度图像gray_img=cv2.imread("lena_gray.jpg",cv2.IMREAD_GRAYSCALE)ifgray_imgisNone:print("图像读取失败!")else:#2.添加方差0.01的高斯噪声img_gaussian=add_gaussian_noise(gray_img,var=0.01)print("高斯噪声添加完成!")#3.三种去噪方法#3×3均值滤波mean3=cv2.blur(img_gaussian,(3,3))#3×3高斯滤波(sigmaX=1)gauss3=cv2.GaussianBlur(img_gaussian,(3,3),sigmaX=1)#5×5高斯滤波(sigmaX=2)gauss5=cv2.GaussianBlur(img_gaussian,(5,5),sigmaX=2)print("三种去噪方法完成!")#4.显示对比cv2.imshow("1.OriginalGrayLena",gray_img)cv2.imshow("2.ImagewithGaussianNoise(var=0.01)",img_gaussian)cv2.imshow("3.MeanFilter(3×3)",mean3)cv2.imshow("4.GaussianFilter(3×3,sigmaX=1)",gauss3)#最优cv2.imshow("5.GaussianFilter(5×5,sigmaX=2)",gauss5)#5.保存最优结果cv2.imwrite("lena_denoised.jpg",gauss3)print("最优去噪图已保存!")cv2.waitKey(0)cv2.destroyAllWindows()解析:3×3高斯滤波在去噪的同时保留了Lena的面部细节,5×5高斯滤波虽去噪更强但细节模糊,均值滤波效果最差,因此选择3×3高斯滤波为最优。2.代码示例:importcv2#1.读取含单一物体的彩色图像(如"apple.jpg")color_img=cv2.imread("apple.jpg",cv2.IMREAD_COLOR)ifcolor_imgisNone:print("物体图像读取失败!")else:#2.步骤1:灰度化gray_img=cv2.cvtColor(color_img,cv2.COLOR_BGR2GRAY)#3.步骤2:高斯滤波去噪(5×5核,sigmaX=1)gray_blur=cv2.GaussianBlur(gray_img,(5,5),sigmaX=1)#4.步骤3:Canny边缘检测(阈值40,120)canny_edges=cv2.Canny(gray_blur,40,120)#5.步骤4:查找最外层轮廓contours,_=cv2.findContours(canny_edges,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)print(f"找到{len(contours)}个物体轮廓!")#6.步骤5:绘制轮廓(红色,线宽2)img_with_contour=color_img.copy()cv2.drawContours(img_with_contour,contours,-1,(0,0,255),2)#7.显示对比cv2.imshow("1.OriginalObjectImage",color_img)cv2.imshow("2.GrayscaleImage",gray_img)cv2.imshow("3.CannyEdges",canny_edges)cv2.imshow("4.ObjectwithRedContour",img_with_contour)#8.保存结果cv2.imwrite("object_contour.jpg",img_with_contour)print("带轮廓的物体图已保存!")cv2.waitKey(0)cv2.destroyAllWindows()解析:cv2.RETR_EXTERNAL确保只保留物体的最外层轮廓,避免内部细节(如苹果的斑点)被误判为独立轮廓;Canny阈值40,120能平衡边缘完整性和噪声抑制,确保物体轮廓清晰。第4章一、选择题答案B解析:A选项warpAffine()支持平移、旋转、缩放,错误;C选项dsize格式为(width,height),与shape的(height,width)相反,错误;D选项需通过flags指定插值方法,错误;B选项正确。C解析:旋转中心为(w//2,h//2)(x=宽度/2,y=高度/2),顺时针旋转角度为-90,缩放0.7,C选项参数全部正确;A选项角度为90(逆时针),B选项旋转中心顺序错误(h//2是y,w//2是x),D选项角度和缩放错误,均错误。C解析:INTER_CUBIC(双三次插值)质量最高,适合放大;INTER_AREA适合缩小,INTER_NEAREST质量最差,INTER_LINEAR中等,C选项正确。A解析:仿射变换需3个点,透视变换需4个点,A正确;B选项相反(仿射保持平行线,透视不保持),C选项函数混淆,D选项两者均支持多种变换,均错误。B解析:flipCode=1为水平翻转,B正确;A是垂直翻转,C是双向翻转,D是仿射变换,均错误。二、填空题答案x轴(水平);y轴(垂直);右解析:平移矩阵中,dx控制水平方向(右为正),dy控制垂直方向(下为正)。fx;fy;拉伸(或变形)解析:fx和fy分别为x和y方向的缩放比例,相同则保持宽高比,避免图像拉伸。3×3;cv2.warpPerspective()解析:透视矩阵为3×3(仿射矩阵为2×3),需用warpPerspective()应用变换。三、实操题答案代码示例:importcv2#1.读取风景图像img=cv2.imread("mountain.jpg",cv2.IMREAD_COLOR)ifimgisNone:print("图像读取失败!")else:#获取原图尺寸h_original,w_original,_=img.shapeprint(f"原图尺寸:宽度={w_original}像素,高度={h_original}像素")#2.步骤1:垂直翻转(flipCode=0)img_flip_v=cv2.flip(img,flipCode=0)print("垂直翻转完成!")#3.步骤2:缩小为原图的60%(fx=0.6,fy=0.6,INTER_AREA插值)img_small=cv2.resize(img_flip_v,dsize=None,fx=0.6,fy=0.6,interpolation=cv2.INTER_AREA)#获取缩小图尺寸h_small,w_small,_=img_small.shapeprint(f"缩小完成!缩小图尺寸:宽度={w_small}像素,高度={h_small}像素")#4.添加文字标注cv2.putText(img,"1.Original",(20,40),cv2.FONT_HERSHEY_SIMPLEX,1,(0,255,0),2)cv2.putText(img_flip_v,"2.FlipVertical(0)",(20,40),cv2.FONT_HERSHEY_SIMPLEX,1,(0,255,0),2)cv2.putText(img_small,"3.Scaled60%(INTER_AREA)",(20,40),cv2.FONT_HERSHEY_SIMPLEX,1,(0,255,0),2)#5.显示对比cv2.imshow("1.OriginalImage",img)cv2.imshow("2.VerticalFlipImage",img_flip_v)cv2.imshow("3.FinalSmallImage",img_small)#6.保存最终结果cv2.imwrite("mountain_final.jpg",img_small)print("最终缩小图像已保存!")cv2.waitKey(0)cv2.destroyAllWindows()解析:垂直翻转后图像上下颠倒(天空在下,地面在上),缩小后无明显模糊(INTER_AREA插值适合缩小),代码中打印尺寸可验证缩放比例是否正确(缩小后尺寸约为原图的60%)。2.代码示例:importcv2importnumpyasnp#1.读取轻微倾斜的文本图像img=cv2.imread("text_slight_tilt.jpg",cv2.IMREAD_COLOR)ifimgisNone:print("文本图像读取失败!")else:h,w,_=img.shapeimg_pts=img.copy()#用于绘制标记点#2.手动选择3个非共线点(文本框的左上、右上、左下,需根据实际图像调整)src_pts=np.float32([[40,50],#左上点(示例值,需修改)[340,60],#右上点(示例值,需修改)[50,180]])#左下点(示例值,需修改)#3.定义目标点(校正为水平,右上点y坐标与左上点相同)dst_pts=np.float32([[40,50],#目标左上(与原图一致)[340,50],#目标右上(y=50,水平)[40,180]])#目标左下(与原图一致)#4.绘制原始点(蓝色圆点,半径5,填充)for(x,y)insrc_pts:cv2.circle(img_pts,(int(x),int(y)),5,(255,0,0),-1)#5.生成仿射变换矩阵M=cv2.getAffineTransform(src_pts,dst_pts)#6.应用仿射变换img_corrected=cv2.warpAffine(img,M,(w,h))#7.添加文字标注cv2.putText(img_pts,"1.Original(3BluePoints)",(20,30),cv2.FONT_HERSHEY_SIMPLEX,0.8,(0,0,255),2)cv2.putText(img_corrected,"2.AffineCorrected(Horizontal)",(20,30),cv2.FONT_HERSHEY_SIMPLEX,0.8,(0,0,255),2)#8.显示对比cv2.imshow("1.OriginalText(withPoints)",img_pts)cv2.imshow("2.CorrectedText",img_corrected)#9.保存校正结果cv2.imwrite("text_affine_final.jpg",img_corrected)print("仿射校正后的文本图已保存!")cv2.waitKey(0)cv2.destroyAllWindows()解析:目标点的设计关键是“让右上点的y坐标与左上点相同”,确保文本水平;若校正后仍有轻微倾斜,微调目标点的y坐标即可(如将目标右上点y设为51)。第5章一、选择题答案B解析:A选项角点是灰度变化剧烈的区域,错误;C选项边缘仅一个方向变化,不属于角点,错误;D选项平面区域灰度无变化,不易误判为角点,错误;B选项正确。B解析:cv2.goodFeaturesToTrack()是Shi-Tomasi角点检测的专用函数,A选项用cv2.cornerHarris(),C/D用cv2.SIFT_create()/cv2.ORB_create(),B正确。C解析:SIFT和SURF受专利保护,ORB是OpenCV开源免费的,C正确。B解析:暴力匹配穷举查询图每个特征点与训练图所有特征点的距离,A/C是FLANN的原理,D无依据,B正确。C解析:单应性矩阵描述坐标映射关系,A是特征检测的作用,B是特征计算的作用,D是匹配筛选的作用,C正确。二、填空题答案角点响应值;0.02~0.04;多(或密集)解析:k控制角点判定的宽松程度,值越小,更多疑似区域被判定为角点。32;128解析:ORB描述子32维,SIFT128维,低维度减少计算量,提高匹配速度。检查的邻域数量;高解析:checks越大,FLANN搜索越彻底,精度越高,但耗时增加。去除外点(或错误匹配对)解析:RANSAC算法能剔除不符合投影关系的错误匹配(外点),确保单应性矩阵准确。三、实操题答案代码示例:importcv2importnumpyasnp#1.读取棋盘格图像img=cv2.imread("chessboard.jpg",cv2.IMREAD_GRAYSCALE)ifimgisNone:print("图像读取失败!")exit()img_color=cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)h,w=img.shape#2.定义3组k值k_values=[0.02,0.04,0.06]result_imgs=[]corner_counts=[]forkink_values:#Harris角点检测img_float=np.float32(img)dst=cv2.cornerHarris(img_float,blockSize=2,ksize=3,k=k)dst=cv2.dilate(dst,None)#统计角点数量threshold=0.01*dst.max()count=np.sum(dst>threshold)corner_counts.append(count)#绘制角点temp_img=img_color.copy()temp_img[dst>threshold]=[0,0,255]#添加标注cv2.putText(temp_img,f"k={k},Count={count}",(20,40),cv2.FONT_HERSHEY_SIMPLEX,1,(255,255,255),2)result_imgs.append(temp_img)#3.拼接结果图(水平拼接)final_img=np.hstack(result_imgs)#4.显示与保存cv2.imshow("HarriskParameterTuning",final_img)cv2.imwrite("harris_param_tune.jpg",final_img)#5.打印统计结果print("Harris角点检测参数统计:")fork,countinzip(k_values,corner_counts):print(f"k={k}:{count}个角点")print("结论:k值越小,检测到的角点越多,密集程度越高;k值越大,角点越少越稀疏。")cv2.waitKey(0)cv2.destroyAllWindows()2.代码示例:importcv2importnumpyasnp#1.读取目标图和场景图img_target=cv2.imread("target.jpg",cv2.IMREAD_COLOR)#目标图img_scene=cv2.imread("scene.jpg",cv2.IMREAD_COLOR)#场景图(gray_target=cv2.cvtColor(img_target,cv2.COLOR_BGR2GRAY)gray_scene=cv2.cvtColor(img_scene,cv2.COLOR_BGR2GRAY)ifimg_targetisNoneorimg_sceneisNone:print("图像读取失败!")exit()#2.ORB特征检测orb=cv2.ORB_create(nfeatures=1000)kp_tar,des_tar=orb.detectAndCompute(gray_target,None)kp_scene,des_scene=orb.detectAndCompute(gray_scene,None)#3.暴力匹配与筛选matcher=cv2.BFMatcher(cv2.NORM_HAMMING,crossCheck=False)matches=matcher.knnMatch(des_tar,des_scene,k=2)good_matches=[]form,ninmatches:ifm.distance<0.75*n.distance:good_matches.append(m)print(f"筛选后匹配对数:{len(good_matches)}")#4.绘制匹配结果img_matches=cv2.drawMatches(img_target,kp_tar,img_scene,kp_scene,good_matches[:30],None,flags=2)cv2.putText(img_matches,f"ORBMatches(Top30)",(20,40),cv2.FONT_HERSHEY_SIMPLEX,1,(0,0,255),2)#5.标记场景图中的目标(匹配对数>30时)img_marked=img_scene.copy()iflen(good_matches)>30:#提取场景图中的目标点坐标pts_scene=np.float32([kp_scene[m.trainIdx].ptformingood_matches])#计算目标点的最小/最大坐标,确定矩形框x_min,y_min=int(min(pts_scene[:,0])),int(min(pts_scene[:,1]))x_max,y_max=int(max(pts_scene[:,0])),int(max(pts_scene[:,1]))#绘制矩形框(绿色,线宽2)cv2.rectangle(img_marked,(x_min,y_min),(x_max,y_max),(0,255,0),2)cv2.putText(img_marked,"Target",(x_min,y_min-10),cv2.FONT_HERSHEY_SIMPLEX,1,(0,255,0),2)print("场景图中检测到目标,已标记!")else:cv2.putText(img_marked,"TargetNotDetected",(20,40),cv2.FONT_HERSHEY_SIMPLEX,1,(0,0,255),2)print("匹配对数不足,未检测到目标!")#6.显示与保存cv2.imshow("1.ORBMatches",img_matches)cv2.imshow("2.MarkedScene",img_marked)cv2.imwrite("target_matches.jpg",img_matches)cv2.imwrite("target_marked.jpg",img_marked)cv2.waitKey(0)cv2.destroyAllWindows()解析:目标标记的核心是“从匹配对中提取场景图的目标点坐标,用最小/最大坐标确定矩形框”;若匹配对数不足,说明场景图中可能不含目标或目标角度/尺度变化过大,需调整ORB参数(如增加nfeatures)。第6章一、选择题答案B解析:Haar级联分类器仅支持单通道图像,检测前需将彩色图转为灰度图,A、C、D错误,B正确。B解析:scaleFactor是检测时图像的缩放比例,值越小检测越精细,A是minSize的作用,C是minNeighbors的作用,D是maxSize的作用,B正确。B解析:减小minNeighbors会降低检测的严格程度,减少漏检,A、C、D会增加漏检或无影响,B正确。B解析:cv2.VideoCapture(0)打开默认摄像头,1表示外接摄像头,A、C、D函数或参数错误,B正确。C解析:提取人脸ROI,仅在ROI内检测眼睛,避免背景干扰,A、B、D无此作用,C正确。二、填空题答案cv2.CascadeClassifier();cv2.CascadeClassifier.detectMultiScale()解析:前者加载模型,后者检测目标,需写完整函数名(含类名)。左上角;宽度和高度解析:(x,y)是目标左上角像素坐标,w是宽度(水平方向),h是高度(垂直方向)。cv2.VideoCapture.read();cv2.VideoCapture.release()解析:read()返回(ret,frame),release()释放摄像头资源,避免占用。ROI(或感兴趣区域)解析:仅对人脸ROI滤波,不影响背景,是局部处理的核心。实操题答案1.代码示例:importcv2#1.加载眼睛级联模型(替换为你的路径)eye_model_path="haarcascade_eye.xml"eye_clf=cv2.CascadeClassifier(eye_model_path)ifeye_clf.empty():print("眼睛模型加载失败!请检查路径。")else:#2.读取含眼睛的图像img=cv2.imread("lena.jpg",cv2.IMREAD_COLOR)ifimgisNone:print("图像读取失败!")else:#3.灰度化gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#4.检测眼睛(参数:眼睛较小,minSize设小)eyes=eye_clf.detectMultiScale(gray,scaleFactor=1.1,minNeighbors=3,minSize=(15,15),#眼睛尺寸小,minSize=15maxSize=(100,100))#5.处理结果iflen(eyes)==0:print("未检测到眼睛!可尝试减小minNeighbors或minSize。")cv2.putText(img,"NoEyesDetected",(50,50),cv2.FONT_HERSHEY_SIMPLEX,1,(0,0,255),2)else:print(f"检测到{len(eyes)}只眼睛!")for(x,y,w,h)ineyes:#绘制蓝色矩形框(B=255,G=0,R=0)cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)cv2.putText(img,"Eye",(x,y-10),cv2.FONT_HERSHEY_SIMPLEX,0.7,(255,0,0),2)#6.显示与保存cv2.imshow("EyeDetectionResult",img)cv2.imwrite("eye_detection.jpg",img)print("眼睛检测结果已保存!")cv2.waitKey(0)cv2.destroyAllWindows()解析:眼睛检测的关键是minSize设小(15~30),因眼睛尺寸通常比人脸小;若未检测到,可减小minNeighbors至2或scaleFactor至1.05。2.代码示例:importcv2#1.加载人脸和微笑模型(替换为你的路径)face_model="haarcascade_frontalface_default.xml"smile_model="haarcascade_smile.xml"face_clf=cv2.CascadeClassifier(face_model)smile_clf=cv2.CascadeClassifier(smile_model)ifface_clf.empty()orsmile_clf.empty():print("模型加载失败!")else:#2.打开默认摄像头cap=cv2.VideoCapture(0)ifnotcap.isOpened():print("摄像头打开失败!")else:print("摄像头已打开,按'q'退出!")whileTrue:ret,frame=cap.read()ifnotret:print("无法读取帧!")breakgray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)#3.检测人脸faces=face_clf.detectMultiScale(gray,1.2,5,(50,50))for(x_face,y_face,w_face,h_face)infaces:#绘制人脸框(绿色)cv2.rectangle(frame,(x_face,y_face),(x_face+w_face,y_face+h_face),(0,255,0),2)cv2.putText(frame,"Face",(x_face,y_face-10),cv2.FONT_HERSHEY_SIMPLEX,0.7,(0,255,0),2)#4.提取人脸ROI(微笑检测仅在ROI内)#微笑通常在人脸下半部分,可缩小ROI范围(y_face+h_face//2开始)smile_roi_gray=gray[y_face+h_face//2:y_face+h_face,x_face:x_face+w_face]smile_roi_color=frame[y_face+h_face//2:y_face+h_face,x_face:x_face+w_face]#5.检测微笑(参数宽松,因微笑特征不明显)smiles=smile_clf.detectMultiScale(smile_roi_gray,scaleFactor=1.1,minNeighbors=2,minSize=(30,30))#绘制微笑框(黄色)for(x_smile,y_smile,w_smile,h_smile)insmiles:cv2.rectangle(smile_roi_color,(x_smile,y_smile),(x_smile+w_smile,y_smile+h_smile),(0,255,255),2)cv2.putText(smile_roi_color,"Smile",(x_smile,y_smile-5),cv2.FONT_HERSHEY_SIMPLEX,0.5,(0,255,255),1)#6.显示实时帧cv2.imshow("Real-timeFace+SmileDetection",frame)#按q退出ifcv2.waitKey(1)&0xFF==ord('q'):break#7.释放资源cap.release()cv2.destroyAllWindows()print("程序退出!")解析:微笑检测需缩小ROI至人脸下半部分(避免检测眼睛区域),且minNeighbors设小(2~3),因微笑特征不如人脸明显;当用户微笑时,人脸下半部分会出现黄色“Smile”框。第7章一、选择题答案B解析:全局阈值适合前景背景灰度差异明显、光照均匀的图像,B选项符合;A、D需Otsu阈值,C需分水岭,均错误。A解析:Otsu的核心是自动计算最优阈值,无需手动调参,A正确;B是分水岭的优势,C需预处理(去噪),D速度比全局阈值慢,均错误。C解析:cv2.drawContours()中线宽设为-1表示填充轮廓内部,实现区域填充,A、B是绘制轮廓线,D无线,均错误。C解析:不确定区域是“背景-前景”的差值区域,即物体边界,算法会自动分割,A是前景,B是背景,D是预处理需过滤的区域,均错误。D解析:分水岭需去噪、阈值分割、开运算,无需提前轮廓提取(分割后自动得到区域),D正确。二、填空题答案0(黑);255(白)解析:THRESH_BINARY_INV是反二进制阈值,与THRESH_BINARY相反,适合前景暗、背景亮的场景。图像预处理(或灰度化→去噪→边缘检测);轮廓提取(或cv2.findContours)解析:轮廓分割需先预处理得到清晰边缘,再提取轮廓,最后填充。距离(或cv2.distanceTransform);膨胀(或cv2.dilate)解析:距离变换得到物体中心(确定前景),膨胀扩大背景,包围所有物体。边界(或不同物体的分隔)解析:分水岭用-1标记边界,方便用户直观区分不同物体。实操题答案1.代码示例:importcv2importnumpyasnp#1.读取手写数字图像img_color=cv2.imread("handwritten_digits.jpg",cv2.IMREAD_COLOR)ifimg_colorisNone:print("图像读取失败!")else:#2.预处理img_gray=cv2.cvtColor(img_color,cv2.COLOR_BGR2GRAY)#高斯滤波(3×3)img_blur=cv2.GaussianBlur(img_gray,(3,3),sigmaX=1)#二值化(反色,数字为白色,背景为黑色,Otsu自动阈值)ret_otsu,img_binary=cv2.threshold(img_blur,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)#3.提取轮廓(最外层轮廓)contours,_=cv2.findContours(img_binary,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)#4.过滤噪声(面积<100)valid_contours=[]forcntincontours:ifcv2.contourArea(cnt)>=100:valid_contours.append(cnt)digit_count=len(valid_contours)print(f"提取到{digit_count}个数字!")#5.定义颜色列表(10种颜色,对应0-9)colors=[(0,255,0),(255,0,0),(0,0,255),(255,255,0),(255,0,255),(0,255,255),(128,0,0),(0,128,0),(0,0,128),(128,128,128)]#6.绘制矩形框和序号fori,cntinenumerate(valid_contours):#获取轮廓的boundingRect(最小矩形)x,y,w,h=cv2.boundingRect(cnt)#绘制矩形框(对应颜色)cv2.rectangle(img_color,(x,y),(x+w,y+h),colors[i%len(colors)],2)#标注序号(i从0开始,对应数字0-9)cv2.putText(img_color,str(i),(x+5,y+20),cv2.FONT_HERSHEY_SIMPLEX,0.8,colors[i%len(colors)],2)#7.添加总数文字cv2.putText(img_color,f"TotalDigits:{digit_count}",(10,30),cv2.FONT_HERSHEY_SIMPLEX,0.8,(0,0,255),2)#8.显示与保存cv2.imshow("HandwrittenDigitsSegmentation",img_color)cv2.imwrite("digits_segmented.jpg",img_color)print("数字分割结果已保存!")cv2.waitKey(0)cv2.destroyAllWindows()解析:用cv2.boundingRect()获取数字的最小矩形,比直接绘制轮廓更直观;颜色列表确保每个数字颜色不同,序号标注清晰,过滤面积<100的噪声,避免误判。2.代码示例:importcv2importnumpyasnp#1.读取重叠坚果图像img_color=cv2.imread("nuts_overlapped.jpg",cv2.IMREAD_COLOR)ifimg_colorisNone:print("坚果图像读取失败!")else:img_gray=cv2.cvtColor(img_color,cv2.COLOR_BGR2GRAY)h,w=img_gray.shapeimg_copy=img_color.copy()#用于显示原图#2.预处理#高斯滤波(5×5)img_blur=cv2.GaussianBlur(img_gray,(5,5),sigmaX=1)#Otsu阈值分割(反色,坚果为白,背景为黑)ret_otsu,img_binary=cv2.threshold(img_blur,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)#开运算(3×3核,1次)kernel=np.ones((3,3),np.uint8)img_open=cv2.morphologyEx(img_binary,cv2.MORPH_OPEN,kernel,iterations=1)#3.确定前景、背景、不确定区域#背景:膨胀3次img_bg=cv2.dilate(img_open,kernel,iterations=3)#前景:距离变换+0.6×最大距离img_dist=cv2.distanceTransform(img_open,cv2.DIST_L2,5)ret_dist,img_fg=cv2.threshold(img_dist,0.6*img_dist.max(),255,0)img_fg=np.uint8(img_fg)#不确定区域img_unknown=cv2.subtract(img_bg,img_fg)#4.创建标记ret_marker,markers=cv2.connectedComponents(img_fg)markers=markers+1#前景标记+1markers[img_unknown==255]=0#不确定区域设为0#5.分水岭分割markers=cv2.watershed(img_color,markers)#边界设为绿色(B=0,G=255,R=0)img_color[markers==-1]=[0,255,0]#6.计数nut_markers=np.unique(markers)nut_count=0formarkerinnut_markers:ifmarker>=2:nut_count+=1print(f"分割出{nut_count}个坚果!")#7.添加计数文字cv2.putText(img_color,f"NutCount:{nut_count}(GreenBoundary)",(10,30),cv2.FONT_HERSHEY_SIMPLEX,0.8,(255,0,0),2)#8.显示与保存cv2.imshow("1.OriginalImage",img_copy)cv2.imshow("2.OtsuBinaryImage",img_binary)cv2.imshow("3.ForegroundImage",img_fg)cv2.imshow("4.WatershedResult",img_color)cv2.imwrite("nuts_watershed.jpg",img_color)print("坚果分割结果已保存!")cv2.waitKey(0)cv2.destroyAllWindows()解析:严格遵循分水岭流程,开运算迭代1次(避免过度平滑),距离变换系数0.6(适合坚果大小),边界用绿色标注,计数通过统计标记值>=2的数量,确保分割准确。第8章一、选择题答案及解析答案:B解析:文档8.2.4明确提到“前景需用‘距离变换+阈值’获取‘确定的物体中心’,避免前景包含重叠区域”,这是区分重叠药片的核心技术;A(高斯滤波)、D(双边滤波)均为去噪操作,C(形态学开运算)用于减少小噪声,均不用于获取物体中心。答案:B解析:文档8.3“前置知识:YOLO模型简介”指出,YOLO与传统两阶段算法的核心区别是“将目标检测视为单一的回归问题,通过一次神经网络计算即可同时预测图像中所有目标的边界框和类别概率,因此检测速度极快”;A(仅支持80种物体)表述片面,YOLO可扩展类别,C(仅处理静态图像)错误,YOLO支持实时视频流,D(无需预训练权重)错误,项目需加载yolov3.weights。答案:A解析:文档8.2.3步骤2代码注释明确说明“增强闭运算,合并更多碎片”,形态学闭运算(先膨胀后腐蚀)的核心作用是合并区域碎片、填补小缺口;B(缩小轮廓)是腐蚀操作效果,C(直接分割重叠区域)是分水岭算法作用,D(黑白反转)是阈值分割(如THRESH_BINARY_INV)作用。答案:B解析:文档8.4.3代码注释中提到“筛选出概率大于50%的”,“prob>0.5”的核心目的是过滤低置信度(<50%)的误检结果,保证检测准确性;A(提高速度)与该条件无关,C(改变边框样式)由cv2.rectangle控制,D(增加类别数量)由object_names.txt和模型决定。答案:C解析:重叠药片计数系统(8.2.3步骤2代码)用“cv2.imwrite("pills_result_v7.jpg",img_color)”保存结果,实时物件检测系统(8.4.3代码)用“cv2.imwrite(filename,last_frame)”保存最后一帧,二者均包含结果保存操作;A(距离变换)仅用于药片系统,B(非最大值抑制)仅用于YOLO系统,D(形态学开运算)仅用于药片系统。二、填空题答案及解析答案:前景背景确定;阈值分割解析:文档8.2.1项目目标1明确“分水岭算法的完整流程:预处理→前景背景确定→标记→分割”;8.2.3步骤1“实验流程”列出“读取图像→灰度化→去噪→阈值分割→开运算→确定前景背景……”,可知预处理阶段包含阈值分割。答案:yolov3.cfg;yolov3.weights解析:文档8.3.2步骤1明确“预训练模型文件:yolov3.cfg(模型配置文件)、yolov3.weights(模型权重文件)”,且8.4.3代码中“net=cv2.dnn.readNetFromDarknet("yolov3.cfg","yolov3.weights")”直接调用这两个文件。答案:0.35*img_dist.max();cv2.connectedComponentsWithStats()解析:文档8.2.3步骤2代码中,距离变换后的阈值设置为“0.35img_dist.max()”(代码行“ret_dist,img_fg=cv2.threshold(img_dist,0.35img_dist.max(),255,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论