
opencv面試復習1 OpenCV 中cv::Mat的深拷貝和淺拷貝問題cv::Mat默認賦值和拷貝構造是淺拷貝只復制矩陣頭信息底層像素數據共享OpenCV 通過引用計數管理內存。這樣可以減少大圖像復制帶來的性能開銷。如果需要真正復制圖像數據需要使用clone()或copyTo()實現深拷貝。2 OpenCV 中 RGB2GRAY 是怎么實現的RGB 轉灰度本質是把三通道彩色圖像轉換為單通道亮度圖像。不是簡單求平均而是按照人眼對不同顏色的敏感程度進行加權求和。常用公式是Gray 0.299R 0.587G 0.114B。在 OpenCV 中由于默認通道順序是 BGR所以通常使用cv::cvtColor(src, gray, cv::COLOR_BGR2GRAY)完成轉換。3 連續圖像轉化為數字圖像需要進行哪些操作連續圖像轉換為數字圖像主要包括采樣和量化兩個過程。采樣是把連續空間坐標離散成有限個像素點決定圖像的空間分辨率量化是把連續的灰度值或顏色值離散成有限等級比如 8 位圖像中像素值范圍是 0 到 255。之后再按照一定圖像格式進行編碼和存儲比如 JPG、PNG 或 BMP。4 數字圖像中有哪些基本特征數字圖像的基本特征包括顏色特征、灰度特征、邊緣特征、紋理特征、形狀特征和局部特征。顏色特征描述圖像的顏色分布灰度特征描述亮度變化邊緣特征反映物體邊界紋理特征反映局部重復結構形狀特征描述目標幾何輪廓局部特征如 SIFT、ORB 可用于圖像匹配和目標識別。5 圖像邊緣檢測中常用的邊緣檢測算子有哪些邊緣檢測本質上是在找灰度變化劇烈的位置而噪聲點也會造成灰度突變。如果不先濾波噪聲也可能被誤檢測為邊緣。使用高斯濾波可以平滑圖像減少噪聲干擾讓邊緣檢測結果更穩定。尤其是 Laplacian 和Canny一般都會先進行高斯濾波。常用邊緣檢測算子主要有 Roberts、Prewitt、Sobel、Scharr、Laplacian、LoG 和 Canny。Roberts 和 Prewitt 屬于比較基礎的一階梯度算子計算簡單但抗噪能力一般。Sobel 是比較常用的一階梯度算子通過 x 和 y 方向模板計算灰度梯度能檢測水平和垂直邊緣并且具有一定平滑效果。Scharr 可以看作 Sobel 的改進在 3×3 卷積核下梯度精度更高。Laplacian 是二階導數算子可以檢測各個方向的邊緣但對噪聲敏感所以通常會先進行高斯濾波。LoG 就是先高斯濾波再做 Laplacian用來提高抗噪能力。6 canny邊緣檢測的流程Canny 邊緣檢測一般包括五個步驟。首先將圖像轉為灰度圖然后通過高斯濾波去除噪聲。接著計算圖像的梯度幅值和梯度方向用來判斷灰度變化劇烈的位置。然后進行非極大值抑制只保留梯度方向上的局部最大值使邊緣變細。最后使用雙閾值檢測區分強邊緣、弱邊緣和非邊緣并通過邊緣連接保留與強邊緣相連的弱邊緣得到最終邊緣圖。所以 Canny 得到的邊緣通常更細、更連續抗噪能力也更好但計算過程比 Sobel 更復雜參數選擇也更重要。灰度圖 → 高斯濾波 → 計算梯度 → 非極大值抑制 → 雙閾值檢測與邊緣連接#includeopencv2/opencv.hpp#includeiostreamintmain(){// 1. 讀取原始圖像// imread 默認以 BGR 三通道格式讀取圖片cv::Mat srccv::imread(road.jpg);// 判斷圖片是否讀取成功if(src.empty()){std::cout讀取圖片失敗std::endl;return-1;}// gray灰度圖// edgesCanny 邊緣檢測結果圖cv::Mat gray;cv::Mat edges;// 2. 將彩色圖像轉換為灰度圖// 霍夫直線檢測通常基于邊緣圖而邊緣檢測一般先在灰度圖上進行cv::cvtColor(src,gray,cv::COLOR_BGR2GRAY);// 3. 高斯濾波降低噪聲// 噪聲可能會被 Canny 誤檢測為邊緣所以先進行平滑處理// Size(5, 5)高斯核大小// 1.5標準差控制模糊程度cv::GaussianBlur(gray,gray,cv::Size(5,5),1.5);// 4. Canny 邊緣檢測// 50低閾值// 150高閾值// Canny 內部會完成梯度計算、非極大值抑制、雙閾值檢測和邊緣連接cv::Canny(gray,edges,50,150);// 5. 用于保存檢測到的直線// Vec4i 中保存一條線段的兩個端點// line[0], line[1] 表示起點坐標 x1, y1// line[2], line[3] 表示終點坐標 x2, y2std::vectorcv::Vec4ilines;// 6. 概率霍夫直線檢測// 輸入必須是邊緣圖一般使用 Canny 的輸出結果cv::HoughLinesP(edges,// 輸入邊緣圖lines,// 輸出檢測到的線段1,// rho 分辨率單位為像素CV_PI/180,// theta 分辨率單位為弧度這里表示 1 度80,// 投票閾值越大檢測出的直線越少50,// 最小線段長度小于該長度的線段會被過濾10// 最大線段間隔小于該間隔的線段會被合并);// 7. 遍歷檢測到的所有直線并畫到原圖上for(constautoline:lines){cv::line(src,// 要繪制的目標圖像cv::Point(line[0],line[1]),// 線段起點cv::Point(line[2],line[3]),// 線段終點cv::Scalar(0,0,255),// 線條顏色BGR 格式這里是紅色2// 線條寬度);}// 8. 顯示 Canny 邊緣檢測結果cv::imshow(edges,edges);// 9. 顯示繪制霍夫直線后的結果圖cv::imshow(lines,src);// 10. 等待按鍵否則窗口會一閃而過cv::waitKey(0);return0;}7 OpenCV 中圖像加法 cv::add() 與圖像融合 cv::addWeighted() 有何區別cv::add() 是圖像加法直接對兩張圖對應位置的像素進行相加結果超過 255 會進行飽和截斷所以容易出現過曝。cv::addWeighted() 是加權融合計算公式是 dst src1 * alpha src2 * beta gamma可以通過 alpha 和 beta 控制兩張圖的融合比例常用于透明疊加、水印、圖像融合和檢測結果可視化。二者都要求輸入圖像的尺寸、通道數和數據類型一致。如果不一致需要先進行 resize() 或顏色空間轉換。