版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1B2A3OpenCV是一套跨平臺的開源計算機視覺庫,提供C++、Python等多語言接口,可免費商用,它能實現(xiàn)圖像與視頻的讀取、處理、分析等基礎(chǔ)操作,還支持特征檢測與匹配、目標(biāo)檢測識別、圖像分割等功能,廣泛應(yīng)用于人臉檢測、二維碼識別、手勢識別、工業(yè)缺陷檢測等場景。4OpenCV2和OpenCV3的核心區(qū)別,從版本架構(gòu)、API規(guī)范、功能新增等關(guān)鍵維度為你梳理,核心差異如下:模塊化架構(gòu)的重大重構(gòu)OpenCV2采用相對松散的模塊組織,功能劃分不夠清晰,部分模塊存在冗余依賴;而OpenCV3進(jìn)行了模塊化的徹底重構(gòu),將庫分為兩大核心部分:opencv_core(核心基礎(chǔ)模塊,免費開源)和opencv_contrib(擴展模塊,包含更多高級、前沿功能,部分涉及專利或商業(yè)授權(quán)),擴展模塊的分離讓核心庫更輕量化,也方便高級功能的獨立迭代和維護(hù)。API命名空間與兼容性變化OpenCV2中大量函數(shù)直接暴露在全局命名空間,容易出現(xiàn)命名沖突;OpenCV3則強化了cv命名空間的使用,規(guī)范了API命名格式,同時引入了版本化的API設(shè)計(部分接口標(biāo)注cv::v3::xxx)。此外,OpenCV3對2.x版本的部分老舊API進(jìn)行了廢棄或重構(gòu),直接遷移2.x代碼可能出現(xiàn)兼容性報錯,需要進(jìn)行少量修改。核心功能與性能的升級新增更多高級計算機視覺算法,尤其在opencv_contrib中包含了SIFT/SURF(專利相關(guān))、ORB優(yōu)化、深度視覺、目標(biāo)跟蹤等前沿功能,這些在OpenCV2中要么缺失,要么實現(xiàn)不夠完善;對底層計算進(jìn)行了優(yōu)化,更好地支持多核處理器、GPU加速(CUDA接口升級),整體運行效率高于OpenCV2;新增了對機器學(xué)習(xí)框架的適配、圖像分割進(jìn)階算法,以及對主流圖像/視頻格式的更好支持。語言接口與生態(tài)的差異OpenCV2對Python接口的支持不夠完善,文檔和生態(tài)相對薄弱;OpenCV3大幅優(yōu)化了Python、Java等高級語言接口,讓非C++開發(fā)者更容易上手,同時配套文檔更齊全,社區(qū)生態(tài)更活躍,后續(xù)的第三方工具和教程也更多圍繞3.x版本展開。構(gòu)建與部署的優(yōu)化OpenCV3升級了構(gòu)建系統(tǒng),更好地支持CMake最新版本,簡化了跨平臺編譯流程(Windows、Linux、Android等),同時減少了第三方依賴庫的冗余,部署后的體積更可控,更適合嵌入式設(shè)備和移動應(yīng)用開發(fā)。1A2BGR(藍(lán)-綠-紅)(而非日常認(rèn)知的RGB順序,這是OpenCV與其他圖像處理庫(如PIL/Pillow)的重要區(qū)別)uint8(8位無符號整數(shù))(取值范圍為0~255,這是圖像存儲中最常見的像素數(shù)據(jù)類型,用于表示每個顏色通道的亮度等級)。3A參數(shù)0(等價于cv2.IMREAD_GRAYSCALE):以灰度單通道模式讀取圖像,直接返回灰度圖4請創(chuàng)建一個大小為300像素×300像素的三通道RGB圖像,并將所有像素值設(shè)置為0,再以(100,50)與(150,100)為頂點繪制一個紅色平面。#導(dǎo)入OpenCV庫importcv2#導(dǎo)入numpy庫(用于創(chuàng)建圖像數(shù)組)importnumpyasnp#1.創(chuàng)建300×300三通道圖像,所有像素值置0#格式說明:np.zeros((高度,寬度,通道數(shù)),數(shù)據(jù)類型)#注意:OpenCV中圖像數(shù)組格式為(H,W,C),這里創(chuàng)建的是三通道圖像(后續(xù)轉(zhuǎn)換為RGB邏輯)img=np.zeros((300,300,3),dtype=np.uint8)#2.繪制紅色矩形(頂點(100,50)與(150,100))#關(guān)鍵說明:OpenCV默認(rèn)圖像色彩空間為BGR,紅色對應(yīng)BGR格式(0,0,255)#矩形繪制函數(shù):cv2.rectangle(圖像,左上角頂點,右下角頂點,顏色,填充方式)#cv2.FILLED表示填充矩形(繪制紅色平面,而非邊框)pt1=(100,50)#第一個頂點(x1,y1)pt2=(150,100)#第二個頂點(x2,y2)red_color=(0,0,255)#OpenCV中BGR格式的紅色cv2.rectangle(img,pt1,pt2,red_color,cv2.FILLED)#3.顯示結(jié)果(驗證效果,OpenCV窗口顯示仍以BGR格式識別)cv2.imshow("RedRectangleImage",img)cv2.waitKey(0)#等待任意按鍵按下cv2.destroyAllWindows()#關(guān)閉所有顯示窗口5.請編寫一個程序,用于錄制計算機攝像頭所拍攝的畫面,并在畫面的左上角繪制自己的名字,最后將錄制結(jié)果保存在文件夾中。#導(dǎo)入OpenCV庫importcv2defrecord_camera_with_name(name="MyName",save_path="camera_record.avi"):#1.初始化攝像頭捕獲對象#參數(shù)0表示默認(rèn)攝像頭(筆記本內(nèi)置攝像頭、臺式機外接第一個攝像頭)cap=cv2.VideoCapture(0)#校驗攝像頭是否成功打開ifnotcap.isOpened():print("錯誤:無法打開攝像頭,請檢查攝像頭是否正常連接或被其他程序占用!")return#2.獲取攝像頭畫面的寬、高和幀率(用于視頻寫入配置)frame_width=int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))frame_height=int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))fps=int(cap.get(cv2.CAP_PROP_FPS))#若攝像頭無法獲取有效幀率,默認(rèn)設(shè)置為25幀/秒iffps<=0:fps=25#3.配置視頻寫入對象(用于保存錄制結(jié)果)#視頻編碼格式:XVID兼容性強,跨平臺可播放,對應(yīng)后綴.avifourcc=cv2.VideoWriter_fourcc(*'XVID')#初始化VideoWriter:(保存路徑,編碼格式,幀率,畫面尺寸)out=cv2.VideoWriter(save_path,fourcc,fps,(frame_width,frame_height))#4.配置文字繪制參數(shù)(左上角繪制姓名)text=name#要繪制的姓名text_position=(20,50)#文字左上角坐標(biāo)(x=20,y=50,貼近左上角)font=cv2.FONT_HERSHEY_SIMPLEX#常用無襯線字體font_scale=1.2#文字大小縮放比例font_color=(0,255,0)#文字顏色(BGR格式,這里是綠色)font_thickness=2#文字線條粗細(xì)print("提示:攝像頭已啟動,錄制中...按下'q'鍵停止錄制并保存文件")#5.循環(huán)捕獲、處理、錄制畫面whileTrue:#讀取一幀攝像頭畫面ret,frame=cap.read()#校驗幀是否讀取成功(攝像頭斷開時會讀取失?。﹊fnotret:print("警告:無法讀取攝像頭畫面,停止錄制")break#在畫面左上角繪制姓名文字cv2.putText(img=frame,text=text,org=text_position,fontFace=font,fontScale=font_scale,color=font_color,thickness=font_thickness)#將處理后的幀寫入視頻文件out.write(frame)#顯示實時錄制畫面(供預(yù)覽)cv2.imshow("CameraRecording(Press'q'toquit)",frame)#按下'q'鍵退出循環(huán)(停止錄制),等待1ms檢測按鍵ifcv2.waitKey(1)&0xFF==ord('q'):break#6.釋放資源(關(guān)鍵步驟,避免內(nèi)存泄漏和文件損壞)cap.release()#釋放攝像頭out.release()#釋放視頻寫入對象(確保文件完整保存)cv2.destroyAllWindows()#關(guān)閉所有OpenCV顯示窗口print(f"錄制完成!視頻文件已保存至:{save_path}")#調(diào)用函數(shù)執(zhí)行錄制(可修改姓名和保存路徑)if__name__=="__main__":#自定義:修改第一個參數(shù)為你的姓名,第二個參數(shù)為自定義保存路徑(如"./record/我的錄制.avi")#注意:若指定子文件夾(如./record/),需提前手動創(chuàng)建該文件夾,否則會保存失敗record_camera_with_name(name="ZhangSan",save_path="my_camera_record.avi")第三章1Dcv2.blur()——該函數(shù)是OpenCV中專門用于實現(xiàn)**均值濾波(又稱方框濾波、平均濾波)**的函數(shù),其原理是取濾波核窗口內(nèi)所有像素的平均值,作為窗口中心像素的新值,實現(xiàn)圖像去噪和平滑。2Acv2.erode()——該函數(shù)是OpenCV中專門用于實現(xiàn)**圖像腐蝕(Erosion)**的專用函數(shù)。腐蝕是形態(tài)學(xué)操作的基礎(chǔ)之一,其原理是用預(yù)設(shè)的結(jié)構(gòu)元素(卷積核)掃描圖像,取窗口內(nèi)像素的最小值替換中心像素值,最終會讓圖像中的亮區(qū)域(前景)收縮、細(xì)化,常用于去除小的亮噪聲、分離相鄰的物體等。3Ccv2.bilateralFilter()——該函數(shù)是OpenCV中專門用于實現(xiàn)雙邊濾波(BilateralFiltering)的專用函數(shù)。雙邊濾波是一種非線性濾波,它同時考慮了空間距離相似度和像素值灰度相似度,在實現(xiàn)圖像去噪平滑的同時,能夠有效保留圖像的邊緣細(xì)節(jié)(避免普通濾波導(dǎo)致的邊緣模糊)。4Bcv2.medianBlur()——這是中值濾波函數(shù)。它通過取像素鄰域內(nèi)的中值來替換中心像素值,對椒鹽噪聲(黑白噪點)有非常好的去除效果,是中值濾波的專用函數(shù)。5A6向下采樣(高斯模糊+降采樣)向上采樣(升采樣+與高斯金字塔的上一層做差)7代碼如下:importcv2importnumpyasnpimportmatplotlib.pyplotasplt#解決matplotlib中文顯示問題plt.rcParams['font.sans-serif']=['SimHei']plt.rcParams['axes.unicode_minus']=Falsedefgaussian_blur_demo():#1.讀取圖像img=cv2.imread('tree.jpg')ifimgisNone:print("錯誤:未找到tree.jpg,請檢查圖像路徑是否正確!")return#轉(zhuǎn)換為RGB格式(方便matplotlib顯示,OpenCV默認(rèn)BGR)img_rgb=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)#2.不同尺寸高斯核濾波#3×3高斯濾波(sigmaX設(shè)為0,OpenCV會自動根據(jù)核尺寸計算sigma)blur_3x3=cv2.GaussianBlur(img,(3,3),sigmaX=0)#7×7高斯濾波blur_7x7=cv2.GaussianBlur(img,(7,7),sigmaX=0)#11×11高斯濾波blur_11x11=cv2.GaussianBlur(img,(11,11),sigmaX=0)#3.兩次3×3高斯濾波blur_3x3_twice=cv2.GaussianBlur(blur_3x3,(3,3),sigmaX=0)#4.轉(zhuǎn)換為RGB格式用于顯示blur_3x3_rgb=cv2.cvtColor(blur_3x3,cv2.COLOR_BGR2RGB)blur_7x7_rgb=cv2.cvtColor(blur_7x7,cv2.COLOR_BGR2RGB)blur_11x11_rgb=cv2.cvtColor(blur_11x11,cv2.COLOR_BGR2RGB)blur_3x3_twice_rgb=cv2.cvtColor(blur_3x3_twice,cv2.COLOR_BGR2RGB)#5.顯示所有結(jié)果plt.figure(figsize=(16,10))#原圖plt.subplot(2,3,1)plt.imshow(img_rgb)plt.title('原圖')plt.axis('off')#3×3濾波結(jié)果plt.subplot(2,3,2)plt.imshow(blur_3x3_rgb)plt.title('3×3高斯濾波')plt.axis('off')#7×7濾波結(jié)果plt.subplot(2,3,3)plt.imshow(blur_7x7_rgb)plt.title('7×7高斯濾波')plt.axis('off')#11×11濾波結(jié)果plt.subplot(2,3,4)plt.imshow(blur_11x11_rgb)plt.title('11×11高斯濾波')plt.axis('off')#兩次3×3濾波結(jié)果plt.subplot(2,3,5)plt.imshow(blur_3x3_twice_rgb)plt.title('兩次3×3高斯濾波')plt.axis('off')#差值圖像(兩次3×3vs7×7)diff=cv2.absdiff(blur_3x3_twice,blur_7x7)diff_rgb=cv2.cvtColor(diff,cv2.COLOR_BGR2RGB)plt.subplot(2,3,6)plt.imshow(diff_rgb)plt.title('兩次3×3與7×7的差值')plt.axis('off')plt.tight_layout()plt.show()#6.驗證結(jié)果是否相同(計算差值的平均值,接近0但非0)diff_mean=np.mean(diff)print(f"兩次3×3高斯濾波與7×7高斯濾波的像素差值平均值:{diff_mean:.6f}")ifdiff_mean==0:print("結(jié)果完全相同")else:print("結(jié)果不相同")#7.解釋原因print("\n原因分析:")print("1.高斯濾波的可分離性:高斯濾波是線性操作,連續(xù)兩次3×3高斯濾波等價于一個“3×3卷積核卷積后再卷積3×3核”的復(fù)合核,但復(fù)合核的尺寸是5×5(而非7×7),且權(quán)重分布與7×7高斯核不同;")print("2.高斯核的權(quán)重分布:3×3高斯核的sigma由OpenCV自動計算(sigma=0.85),兩次卷積的復(fù)合核權(quán)重和7×7高斯核(sigma≈1.91)的權(quán)重分布差異顯著;")print("3.數(shù)值精度:即使理論上近似,OpenCV的浮點運算精度限制也會導(dǎo)致像素值存在微小差異。")if__name__=="__main__":gaussian_blur_demo()8代碼如下:importcv2importnumpyasnpimportmatplotlib.pyplotasplt#解決matplotlib中文顯示問題plt.rcParams['font.sans-serif']=['SimHei']plt.rcParams['axes.unicode_minus']=Falsedefcompare_resize_methods():#1.讀取圖像img=cv2.imread('mountain.jpg')ifimgisNone:print("錯誤:未找到mountain.jpg,請檢查圖像路徑是否正確!")return#轉(zhuǎn)換為RGB格式(matplotlib顯示用,OpenCV默認(rèn)BGR)img_rgb=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)h,w=img.shape[:2]print(f"原始圖像尺寸:{w}×{h}")#2.方式1:cv2.resize()三次縮?。看螌捀呖s為1/2)resize_imgs=[img_rgb]#存儲每次resize的結(jié)果,初始為原圖current_resize=img.copy()foriinrange(3):#計算新尺寸:寬高各縮為1/2new_w=current_resize.shape[1]//2new_h=current_resize.shape[0]//2#使用默認(rèn)插值方式(cv2.INTER_LINEAR)縮小current_resize=cv2.resize(current_resize,(new_w,new_h))#轉(zhuǎn)換為RGB存儲resize_imgs.append(cv2.cvtColor(current_resize,cv2.COLOR_BGR2RGB))print(f"第{i+1}次resize后尺寸:{new_w}×{new_h}")#3.方式2:cv2.pyrDown()三次縮?。ǜ咚菇鹱炙虏蓸樱﹑yrdown_imgs=[img_rgb]#存儲每次pyrDown的結(jié)果,初始為原圖current_pyr=img.copy()foriinrange(3):current_pyr=cv2.pyrDown(current_pyr)#轉(zhuǎn)換為RGB存儲pyrdown_imgs.append(cv2.cvtColor(current_pyr,cv2.COLOR_BGR2RGB))pyr_h,pyr_w=current_pyr.shape[:2]print(f"第{i+1}次pyrDown后尺寸:{pyr_w}×{pyr_h}")#4.可視化對比結(jié)果plt.figure(figsize=(16,12))#顯示原圖plt.subplot(4,3,1)plt.imshow(img_rgb)plt.title('原圖')plt.axis('off')#顯示resize各次結(jié)果foriinrange(1,4):plt.subplot(4,3,i+1)plt.imshow(resize_imgs[i])plt.title(f'第{i}次cv2.resize()')plt.axis('off')#顯示pyrDown各次結(jié)果foriinrange(1,4):plt.subplot(4,3,i+4)plt.imshow(pyrdown_imgs[i])plt.title(f'第{i}次cv2.pyrDown()')plt.axis('off')#對比最終結(jié)果(第三次縮小)plt.subplot(4,3,8)plt.imshow(resize_imgs[3])plt.title('最終:cv2.resize()×3')plt.axis('off')plt.subplot(4,3,9)plt.imshow(pyrdown_imgs[3])plt.title('最終:cv2.pyrDown()×3')plt.axis('off')#計算最終結(jié)果的差值(直觀顯示差異)#先統(tǒng)一尺寸(確保兩者尺寸一致,pyrDown和resize理論尺寸相同)final_resize=resize_imgs[3]final_pyr=pyrdown_imgs[3]diff=cv2.absdiff(cv2.cvtColor(final_resize,cv2.COLOR_RGB2BGR),cv2.cvtColor(final_pyr,cv2.COLOR_RGB2BGR))diff_rgb=cv2.cvtColor(diff,cv2.COLOR_BGR2RGB)plt.subplot(4,3,10)plt.imshow(diff_rgb)plt.title('最終結(jié)果差值(resize-pyrDown)')plt.axis('off')plt.tight_layout()plt.show()#5.輸出差異分析print("\n=====兩種縮小方式的核心差異=====")print("1.處理邏輯:")print("-cv2.resize():直接對圖像像素進(jìn)行插值縮放(默認(rèn)雙線性插值),無預(yù)處理,僅改變像素排列;")print("-cv2.pyrDown():先對圖像進(jìn)行高斯模糊(消除混疊效應(yīng)),再移除偶數(shù)行/列縮小,屬于高斯金字塔下采樣。")print("2.視覺效果:")print("-cv2.resize():多次縮小后易出現(xiàn)鋸齒、摩爾紋、細(xì)節(jié)失真(混疊);")print("-cv2.pyrDown():多次縮小后圖像更平滑,無明顯鋸齒,細(xì)節(jié)過渡自然,但會丟失更多高頻細(xì)節(jié)。")print("3.尺寸一致性:")print("-兩者每次縮小后寬高均為原來的1/2,3次后尺寸均為原圖的1/8(寬高)、1/64(面積);")print("-但像素值分布差異顯著,pyrDown因高斯模糊整體更“柔”,resize保留更多原始像素的硬邊緣。")if__name__=="__main__":compare_resize_methods()第四章1A2A3B4A5A6計算圖像的直方圖,對圖像進(jìn)行直方圖均衡化處理。7程序代碼如下:importcv2importnumpyasnpimportmatplotlib.pyplotasplt#解決matplotlib中文顯示問題plt.rcParams['font.sans-serif']=['SimHei']plt.rcParams['axes.unicode_minus']=Falsedefcanny_threshold_experiment():#1.讀取圖像并轉(zhuǎn)為灰度圖img_path="DavidL.jpg"img=cv2.imread(img_path)ifimgisNone:print(f"錯誤:未找到圖像{img_path},請檢查文件路徑是否正確!")returnimg_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#Canny需基于灰度圖處理img_rgb=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)#轉(zhuǎn)換為RGB用于matplotlib顯示#2.定義5組測試參數(shù)(threshold1:低閾值,threshold2:高閾值)threshold_groups=[(0,50,"threshold1=0,threshold2=50"),(50,100,"threshold1=50,threshold2=100"),(100,150,"threshold1=100,threshold2=150"),(150,200,"threshold1=150,threshold2=200"),(200,250,"threshold1=200,threshold2=250")]#3.對每組參數(shù)執(zhí)行Canny邊緣檢測canny_results=[]fort1,t2,titleinthreshold_groups:edges=cv2.Canny(img_gray,t1,t2)#核心Canny函數(shù)調(diào)用canny_results.append((edges,title))#4.可視化所有結(jié)果plt.figure(figsize=(18,12))#顯示原圖plt.subplot(2,3,1)plt.imshow(img_rgb)plt.title("原圖")plt.axis("off")#顯示5組Canny結(jié)果fori,(edges,title)inenumerate(canny_results):plt.subplot(2,3,i+2)plt.imshow(edges,cmap="gray")plt.title(title)plt.axis("off")plt.tight_layout()plt.show()#5.逐一分析每組參數(shù)的效果print("\n=====Canny閾值參數(shù)對邊緣檢測效果的影響分析=====")print("【核心原理】:Canny的雙閾值規(guī)則——")print("-高于threshold2(高閾值):判定為強邊緣,直接保留;")print("-低于threshold1(低閾值):判定為非邊緣,直接舍棄;")print("-介于兩者之間:僅當(dāng)與強邊緣相連時,才判定為邊緣保留。")print("\n【各組參數(shù)效果】:")#第1組:threshold1=0,threshold2=50print("\n(1)threshold1=0,threshold2=50:")print("效果:邊緣數(shù)量極多,畫面幾乎全白,包含大量噪聲和偽邊緣;")print("原因:高閾值50過低,幾乎所有像素梯度都被判定為強邊緣,低閾值0無過濾作用,噪聲完全保留。")#第2組:threshold1=50,threshold2=100print("\n(2)threshold1=50,threshold2=100:")print("效果:邊緣數(shù)量較多,能清晰看到主體輪廓,但仍有少量細(xì)碎的噪聲邊緣;")print("原因:閾值適中,核心邊緣(如人物輪廓、五官)被保留,同時少量低梯度的噪聲/細(xì)節(jié)也被檢測到。")#第3組:threshold1=100,threshold2=150print("\n(3)threshold1=100,threshold2=150:")print("效果:邊緣數(shù)量適中,主體輪廓清晰且無明顯噪聲,是本次實驗中效果最優(yōu)的參數(shù)組合;")print("原因:高低閾值比例約1:1.5(接近工業(yè)界推薦的1:2/1:3),既過濾了噪聲,又保留了關(guān)鍵邊緣。")#第4組:threshold1=150,threshold2=200print("\n(4)threshold1=150,threshold2=200:")print("效果:邊緣數(shù)量減少,僅保留高梯度的強邊緣(如五官輪廓、頭發(fā)邊緣),部分細(xì)節(jié)邊緣丟失;")print("原因:閾值升高,大量中等梯度的邊緣(如皮膚紋理)被舍棄,僅保留對比度極高的核心邊緣。")#第5組:threshold1=200,threshold2=250print("\n(5)threshold1=200,threshold2=250:")print("效果:邊緣極少,僅能看到極少數(shù)超高梯度的邊緣(如眼睛、頭發(fā)的強對比處),主體輪廓幾乎丟失;")print("原因:閾值過高,只有極少數(shù)像素梯度能達(dá)到高閾值,大部分邊緣被判定為非邊緣舍棄。")if__name__=="__main__":canny_threshold_experiment()8程序代碼如下:importcv2importnumpyasnpimportmatplotlib.pyplotasplt#解決matplotlib中文顯示問題plt.rcParams['font.sans-serif']=['SimHei']plt.rcParams['axes.unicode_minus']=Falsedefhough_transform_car_demo():#1.讀取圖像img_path="Car.jpg"img=cv2.imread(img_path)ifimgisNone:print(f"錯誤:未找到圖像{img_path},請檢查文件路徑是否正確!")return#轉(zhuǎn)換為RGB格式(matplotlib顯示用)img_rgb=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)#轉(zhuǎn)為灰度圖(霍夫變換的基礎(chǔ))img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#邊緣檢測(預(yù)處理,提升霍夫變換準(zhǔn)確性)edges=cv2.Canny(img_gray,50,150,apertureSize=3)#----------------------霍夫線變換----------------------#使用概率霍夫線變換(HoughLinesP),參數(shù)適配汽車圖像特征lines=cv2.HoughLinesP(edges,#邊緣圖rho=1,#像素精度theta=np.pi/180,#角度精度threshold=80,#閾值(越高檢測的直線越少,越精準(zhǔn))minLineLength=50,#最小線段長度(過濾短雜線)maxLineGap=10#線段最大間隙(允許斷開的間隙))#繪制霍夫線變換結(jié)果img_lines=img_rgb.copy()iflinesisnotNone:forlineinlines:x1,y1,x2,y2=line[0]#用紅色繪制檢測到的直線(線寬2)cv2.line(img_lines,(x1,y1),(x2,y2),(255,0,0),2)#----------------------霍夫圓變換----------------------#霍夫圓變換對噪聲敏感,先做高斯模糊img_blur=cv2.GaussianBlur(img_gray,(9,9),2)#霍夫圓變換(適配汽車車輪檢測)circles=cv2.HoughCircles(img_blur,#模糊后的灰度圖method=cv2.HOUGH_GRADIENT,#梯度法(唯一支持的方法)dp=1,#分辨率縮放因子(1為原圖分辨率)minDist=100,#圓心之間的最小距離(避免重復(fù)檢測)param1=100,#Canny邊緣檢測的高閾值param2=30,#圓心檢測閾值(越低檢測的圓越多)minRadius=20,#最小圓半徑(過濾小圓)maxRadius=100#最大圓半徑(過濾大圓))#繪制霍夫圓變換結(jié)果img_circles=img_rgb.copy()ifcirclesisnotNone:#轉(zhuǎn)換為整數(shù)(圓參數(shù)是浮點型)circles=np.uint16(np.around(circles))forcircleincircles[0,:]:center=(circle[0],circle[1])#圓心坐標(biāo)radius=circle[2]#半徑#繪制圓心(綠色點,大小6)cv2.circle(img_circles,center,1,(0,255,0),6)#繪制圓周(綠色線,線寬2)cv2.circle(img_circles,center,radius,(0,255,0),2)#----------------------可視化結(jié)果----------------------plt.figure(figsize=(18,6))#原圖plt.subplot(1,3,1)plt.imshow(img_rgb)plt.title('原圖')plt.axis('off')#霍夫線變換結(jié)果plt.subplot(1,3,2)plt.imshow(img_lines)plt.title('霍夫線變換結(jié)果')plt.axis('off')#霍夫圓變換結(jié)果plt.subplot(1,3,3)plt.imshow(img_circles)plt.title('霍夫圓變換結(jié)果')plt.axis('off')plt.tight_layout()plt.show()#----------------------效果分析----------------------print("\n=====霍夫變換對Car.jpg的處理效果分析=====")print("1.霍夫線變換的圖像變化:")print("-核心變化:圖像上疊加了紅色的直線,這些直線對應(yīng)汽車的邊緣特征(如車身輪廓、車窗邊框、保險杠線條、地面標(biāo)線等);")print("-視覺效果:原本的汽車圖像被“結(jié)構(gòu)化”,能清晰看到構(gòu)成汽車的直線元素,雜亂的細(xì)節(jié)被過濾,僅保留直線特征;")print("-特點:檢測的直線數(shù)量由閾值控制,閾值越高,直線越少,僅保留最明顯的強直線(如車身主輪廓)。")print("\n2.霍夫圓變換的圖像變化:")print("-核心變化:圖像上疊加了綠色的圓形(圓心+圓周),主要檢測到汽車的車輪(輪胎/輪轂)等圓形特征;")print("-視覺效果:能精準(zhǔn)定位圓形目標(biāo)的位置和大小,非圓形區(qū)域無額外繪制,突出汽車的圓形部件;")print("-特點:對噪聲敏感,需先高斯模糊預(yù)處理,參數(shù)(如minDist、param2)會影響圓的檢測數(shù)量和準(zhǔn)確性。")if__name__=="__main__":hough_transform_car_demo()第五章1A2A3A4C5程序代碼如下:importcv2importnumpyasnpimportmatplotlib.pyplotasplt#解決matplotlib中文顯示問題plt.rcParams['font.sans-serif']=['SimHei']plt.rcParams['axes.unicode_minus']=Falsedefdetect_circle_contour():#1.讀取圖像img_path="circle.jpg"img=cv2.imread(img_path)ifimgisNone:print(f"錯誤:未找到圖像{img_path},請檢查文件路徑是否正確!")return#2.轉(zhuǎn)換為灰度圖像img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#3.閾值化處理(轉(zhuǎn)為二值圖像)#參數(shù):灰度圖、閾值、最大值、二值化類型(THRESH_BINARY_INV適用于白底黑圓的情況,可根據(jù)圖像調(diào)整)#若圖像是黑底白圓,改用cv2.THRESH_BINARYret,img_binary=cv2.threshold(img_gray,127,255,cv2.THRESH_BINARY_INV)#4.檢測輪廓#參數(shù):二值圖像、輪廓檢索模式(RETR_EXTERNAL只檢測最外層)、輪廓逼近方法(CHAIN_APPROX_SIMPLE壓縮點)contours,hierarchy=cv2.findContours(img_binary,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)#5.繪制輪廓(可視化)img_contour=img.copy()#復(fù)制原圖用于繪制輪廓ifcontours:#取面積最大的輪廓(確保是圓形的主輪廓,過濾噪聲)main_contour=max(contours,key=cv2.contourArea)#繪制輪廓:綠色,線寬2,-1表示繪制所有輪廓點cv2.drawContours(img_contour,[main_contour],-1,(0,255,0),2)#輸出輪廓關(guān)鍵信息print("=====圓形輪廓關(guān)鍵信息=====")print(f"輪廓點數(shù)量:{len(main_contour)}")print(f"輪廓面積:{cv2.contourArea(main_contour):.2f}像素")#計算最小包圍圓(驗證圓形特征)(cx,cy),radius=cv2.minEnclosingCircle(main_contour)print(f"最小包圍圓圓心:({cx:.2f},{cy:.2f}),半徑:{radius:.2f}像素")else:print("未檢測到任何輪廓,請檢查閾值化參數(shù)或圖像內(nèi)容!")#6.可視化所有步驟結(jié)果plt.figure(figsize=(16,4))#原圖plt.subplot(1,4,1)plt.imshow(cv2.cvtColor(img,cv2.COLOR_BGR2RGB))plt.title('原圖')plt.axis('off')#灰度圖plt.subplot(1,4,2)plt.imshow(img_gray,cmap='gray')plt.title('灰度圖像')plt.axis('off')#二值化圖像plt.subplot(1,4,3)plt.imshow(img_binary,cmap='gray')plt.title('閾值化二值圖像')plt.axis('off')#輪廓檢測結(jié)果plt.subplot(1,4,4)plt.imshow(cv2.cvtColor(img_contour,cv2.COLOR_BGR2RGB))plt.title('輪廓檢測結(jié)果')plt.axis('off')plt.tight_layout()plt.show()if__name__=="__main__":detect_circle_contour()6程序代碼如下:importcv2importnumpyasnpimportmatplotlib.pyplotasplt#解決matplotlib中文顯示問題plt.rcParams['font.sans-serif']=['SimHei']plt.rcParams['axes.unicode_minus']=Falsedefcontour_approx_demo():#1.構(gòu)造基礎(chǔ)輪廓(不規(guī)則多邊形,周長≈110,作為基長度)#手動構(gòu)造點集,確保輪廓周長接近110points=np.array([[50,50],[70,30],[100,40],[120,60],[110,90],[90,100],[60,90],[40,70],[50,50]#閉合輪廓],dtype=32)#調(diào)整為OpenCV輪廓的格式((N,1,2))original_contour=points.reshape((-1,1,2))#計算原始輪廓的周長(作為基長度參考)base_length=cv2.arcLength(original_contour,closed=True)print(f"原始輪廓周長(基長度參考):{base_length:.2f}(目標(biāo)基長度110)")#2.定義逼近精度比例(90%、66%、33%、10%)ratios=[0.9,0.66,0.33,0.1]ratio_labels=["90%","66%","33%","10%"]#基于基長度110計算每個比例對應(yīng)的ε(逼近精度)epsilon_list=[110*ratioforratioinratios]#3.對每個ε執(zhí)行輪廓逼近approx_contours=[]fori,(epsilon,label)inenumerate(zip(epsilon_list,ratio_labels)):#cv2.approxPolyDP(輪廓,逼近精度ε,是否閉合)approx=cv2.approxPolyDP(original_contour,epsilon,closed=True)approx_contours.append((approx,label,epsilon))#計算逼近后輪廓的周長approx_length=cv2.arcLength(approx,closed=True)print(f"\n{label}逼近(ε={epsilon:.2f}):")print(f"逼近后輪廓頂點數(shù):{len(approx)}")print(f"逼近后輪廓周長:{approx_length:.2f}")#4.可視化原始輪廓和所有逼近結(jié)果plt.figure(figsize=(15,10))#繪制原始輪廓plt.subplot(2,3,1)#提取輪廓點的x、y坐標(biāo)x_ori=original_contour[:,0,0]y_ori=original_contour[:,0,1]plt.plot(x_ori,y_ori,'b-',linewidth=2,label='原始輪廓')plt.fill(x_ori,y_ori,'lightblue',alpha=0.3)plt.title(f'原始輪廓(周長≈{base_length:.2f})')plt.axis('equal')#等比例顯示,避免輪廓變形plt.legend()#繪制4種逼近結(jié)果fori,(approx,label,epsilon)inenumerate(approx_contours):plt.subplot(2,3,i+2)x_approx=approx[:,0,0]y_approx=approx[:,0,1]plt.plot(x_ori,y_ori,'gray--',linewidth=1,label='原始輪廓(參考)')plt.plot(x_approx,y_approx,'r-',linewidth=2,label=f'{label}逼近')plt.fill(x_approx,y_approx,'lightcoral',alpha=0.3)plt.title(f'{label}逼近(ε={epsilon:.2f})')plt.axis('equal')plt.legend()plt.tight_layout()plt.show()if__name__=="__main__":contour_approx_demo()
第六章1A2A3人臉識別的基本步驟是人臉檢測和人臉識別/人臉驗證,后者對檢測到的人臉進(jìn)行特征提取與身份匹配/身份確認(rèn)。4程序代碼如下:importcv2importosimportnumpyasnp#=====================1.配置參數(shù)=====================#人臉檢測分類器路徑(OpenCV自帶,若找不到需手動指定路徑)CASCADE_PATH=cv2.data.haarcascades+"haarcascade_frontalface_default.xml"#訓(xùn)練數(shù)據(jù)保存路徑TRAIN_DIR="train_data"#模型保存路徑MODEL_PATH="model/face_model.yml"#人臉圖像尺寸(統(tǒng)一大小,方便訓(xùn)練)FACE_SIZE=(100,100)#你的身份標(biāo)簽(數(shù)字,比如0,代表唯一身份)YOUR_LABEL=0#你的名字(對應(yīng)標(biāo)簽,用于識別結(jié)果顯示)YOUR_NAME="我自己"#=====================2.工具函數(shù)=====================defcreate_dir(dir_path):"""創(chuàng)建文件夾(若不存在)"""ifnotos.path.exists(dir_path):os.makedirs(dir_path)defdetect_face(img_gray):"""檢測人臉并返回裁剪后的人臉圖像"""#加載人臉檢測分類器face_cascade=cv2.CascadeClassifier(CASCADE_PATH)ifface_cascade.empty():raiseException("人臉檢測分類器加載失敗,請檢查CASCADE_PATH是否正確!")#檢測人臉faces=face_cascade.detectMultiScale(img_gray,scaleFactor=1.1,minNeighbors=5,minSize=(30,30))iflen(faces)==0:returnNone,None#未檢測到人臉#取第一個檢測到的人臉(默認(rèn)只有一個人)x,y,w,h=faces[0]#裁剪人臉區(qū)域并統(tǒng)一尺寸face_roi=img_gray[y:y+h,x:x+w]face_roi=cv2.resize(face_roi,FACE_SIZE)returnface_roi,(x,y,w,h)#=====================3.采集人臉數(shù)據(jù)=====================defcollect_face_data(num_photos=20):"""調(diào)用攝像頭采集num_photos張人臉照片(默認(rèn)20張,越多訓(xùn)練效果越好)"""create_dir(TRAIN_DIR)cap=cv2.VideoCapture(0)#打開攝像頭(0為默認(rèn)攝像頭)count=0#已采集的照片數(shù)print(f"\n開始采集人臉數(shù)據(jù),需要拍攝{num_photos}張照片...")print("提示:請正對攝像頭,緩慢移動頭部,按空格鍵拍攝,按q鍵退出!")whilecount<num_photos:ret,frame=cap.read()ifnotret:print("攝像頭讀取失敗!")breakimg_gray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)face_roi,face_rect=detect_face(img_gray)#繪制人臉檢測框ifface_rectisnotNone:x,y,w,h=face_rectcv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)cv2.putText(frame,f"已采集:{count}/{num_photos}",(10,30),cv2.FONT_HERSHEY_SIMPLEX,1,(255,0,0),2)cv2.imshow("CollectFaceData",frame)#按鍵操作key=cv2.waitKey(1)&0xFFifkey==ord('q'):#按q退出breakelifkey==ord(''):#按空格鍵拍攝ifface_roiisnotNone:#保存人臉圖像photo_path=os.path.join(TRAIN_DIR,f"face_{count}.png")cv2.imwrite(photo_path,face_roi)count+=1print(f"已保存第{count}張人臉照片:{photo_path}")cap.release()cv2.destroyAllWindows()ifcount==num_photos:print(f"\n人臉數(shù)據(jù)采集完成!共采集{count}張照片,保存至{TRAIN_DIR}文件夾。")else:print(f"\n采集中斷,僅保存了{(lán)count}張照片(需要{num_photos}張)。")#=====================4.訓(xùn)練人臉識別模型=====================deftrain_face_model():"""加載訓(xùn)練數(shù)據(jù),訓(xùn)練LBPH人臉識別模型"""create_dir(os.path.dirname(MODEL_PATH))faces=[]#存儲人臉圖像數(shù)據(jù)labels=[]#存儲對應(yīng)的標(biāo)簽#遍歷訓(xùn)練數(shù)據(jù)文件夾forfilenameinos.listdir(TRAIN_DIR):iffilename.endswith(".png")orfilename.endswith(".jpg"):#讀取人臉圖像img_path=os.path.join(TRAIN_DIR,filename)face_img=cv2.imread(img_path,0)#以灰度圖讀取ifface_imgisNone:continue#添加到訓(xùn)練集faces.append(face_img)labels.append(YOUR_LABEL)iflen(faces)==0:raiseException(f"訓(xùn)練數(shù)據(jù)為空!請先運行collect_face_data()采集人臉照片。")print(f"\n開始訓(xùn)練模型,共加載{len(faces)}張訓(xùn)練圖像...")#創(chuàng)建LBPH人臉識別器(適合新手,參數(shù)為默認(rèn)值)recognizer=cv2.face.LBPHFaceRecognizer_create()#訓(xùn)練模型recognizer.train(faces,np.array(labels))#保存模型recognizer.save(MODEL_PATH)print(f"模型訓(xùn)練完成!已保存至{MODEL_PATH}")returnrecognizer#=====================5.測試人臉識別模型=====================deftest_face_recognition(test_mode="camera"):"""測試模型:支持?jǐn)z像頭實時識別(camera)或單張照片識別(photo)"""#加載訓(xùn)練好的模型ifnotos.path.exists(MODEL_PATH):raiseException(f"模型文件不存在!請先運行train_face_model()訓(xùn)練模型。")recognizer=cv2.face.LBPHFaceRecognizer_create()recognizer.read(MODEL_PATH)iftest_mode=="camera":#攝像頭實時識別cap=cv2.VideoCapture(0)print("\n開始實時人臉識別,按q鍵退出!")print("置信度越低,匹配度越高(通常<50為匹配)")whileTrue:ret,frame=cap.read()ifnotret:breakimg_
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026華夏銀行秋招試題及答案
- 循證護(hù)理與護(hù)理科研
- 2026年智能鹽氯機項目公司成立分析報告
- 2026年熱氣球旅游項目可行性研究報告
- 官方開年活動策劃方案(3篇)
- 紅酒互動活動策劃方案(3篇)
- 初中化學(xué)氣體制備裝置智能監(jiān)測系統(tǒng)構(gòu)建課題報告教學(xué)研究課題報告
- 小學(xué)英語教學(xué)中案例教學(xué)與數(shù)字英語口語互動軟件的實踐研究教學(xué)研究課題報告
- 企業(yè)企業(yè)文化與員工行為手冊
- CPU新技術(shù)介紹教學(xué)課件
- 老同學(xué)聚會群主的講話發(fā)言稿
- 國家開放大學(xué)最新《監(jiān)督學(xué)》形考任務(wù)(1-4)試題解析和答案
- 天然氣輸氣管線陰極保護(hù)施工方案
- 高血壓問卷調(diào)查表
- QC成果提高花崗巖磚鋪裝質(zhì)量
- GB/T 25156-2010橡膠塑料注射成型機通用技術(shù)條件
- GB/T 25085.3-2020道路車輛汽車電纜第3部分:交流30 V或直流60 V單芯銅導(dǎo)體電纜的尺寸和要求
- GB/T 242-2007金屬管擴口試驗方法
- GB/T 21776-2008粉末涂料及其涂層的檢測標(biāo)準(zhǔn)指南
- 第六單元作文素材:批判與觀察 高一語文作文 (統(tǒng)編版必修下冊)
- 全新版尹定邦設(shè)計學(xué)概論1課件
評論
0/150
提交評論