<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ##圖像濾波基礎 **一:基本概念** 濾波是數字圖像處理中的一個基本操作,在信號處理領域可以說無處不在。圖像濾波,即在盡量保留圖像細節特征的條件下對目標圖像的噪聲進行抑制,通常是數字圖像處理中不可缺少的操作,其處理效果的好壞將直接影響到后續運算和分析的效果。簡單來說,圖像濾波的根本目的是在圖像中提取出人類感興趣的特征。 當我們觀察一幅圖像時,有兩種處理方法:? 1\. 觀察不同的灰度(或彩色值)在圖像中的分布情況,即空間分布。? 2\. 觀察圖像中的灰度(或彩色值)的變化情況,這涉及到頻率方面的問題。 因此,圖像濾波分為頻域和空域濾波,簡單來說,空域指用圖像的灰度值來描述一幅圖像;而頻域指用圖像灰度值的變化來描述一幅圖像。而低通濾波器和高通濾波器的概念就是在頻域中產生的。低通濾波器旨在去除圖像中的高頻成分,而高通濾波器則是去除了圖像中的低頻成分。 這里簡單記錄以下低通濾波器中的均值和高斯濾波器(線性濾波器)、中值濾波器(非線性濾波器);高通濾波器中的sobel算子(方向濾波器)和拉普拉斯變換(二階導數),其中,sobel算子和拉普拉斯變換均可以對圖像的邊緣進行檢測。 **二:低通濾波器** 消除圖像中的噪聲成分叫作圖像的平滑化或低通濾波。信號或圖像的能量大部分集中在幅度譜的低頻和中頻段是很常見的,而在較高頻段,感興趣的信息經常被噪聲淹沒。因此一個能降低高頻成分幅度的濾波器就能夠減弱噪聲的影響。 圖像濾波的目的有兩個:一是抽出對象的特征作為圖像識別的特征模式;另一個是為適應圖像處理的要求,消除圖像數字化時所混入的噪聲。當然,在設計低通濾波器時,要考慮到濾波對圖像造成的細節丟失等問題。 平滑濾波是低頻增強的空間域濾波技術。它的目的有兩類:一類是圖像模糊;另一類是濾除圖像噪聲。空間域的平滑濾波一般采用簡單平均法進行,就是求鄰近像元點的平均灰度值或亮度值。鄰域的大小與平滑的效果直接相關,鄰域越大平滑的效果越好,但鄰域過大,平滑會使邊緣信息損失的越大,從而使輸出的圖像變得模糊,因此需合理選擇鄰域的大小。 關于濾波器,一種形象的比喻法是:我們可以把濾波器想象成一個包含加權系數的窗口,當使用這個濾波器平滑處理圖像時,就把這個窗口放到圖像之上,透過這個窗口來看我們得到的圖像。 濾波器的種類有很多, 在OpenCV中,提供了如下幾種常用的圖像平滑處理操作方法及函數:? 1\. 領域均值濾波:blur函數,將圖像的每個像素替換為相鄰矩形內像素的平均值(均值濾波)? 2\. 高斯低通濾波:GaussianBlur函數? 3\. 方框濾波:boxblur函數? 4\. 中值濾波:medianBlur函數? 5\. 雙邊濾波:bilateralFilter函數 以下是均值濾波和高斯低通濾波的簡單代碼,在Qt中新建控制臺項目,在.pro文件中添加以下內容: ~~~ INCLUDEPATH+=C:\OpenCV\install\include\opencv\ C:\OpenCV\install\include\opencv2\ C:\OpenCV\install\include LIBS+=C:\OpenCV\lib\libopencv_calib3d249.dll.a\ C:\OpenCV\lib\libopencv_contrib249.dll.a\ C:\OpenCV\lib\libopencv_core249.dll.a\ C:\OpenCV\lib\libopencv_features2d249.dll.a\ C:\OpenCV\lib\libopencv_flann249.dll.a\ C:\OpenCV\lib\libopencv_gpu249.dll.a\ C:\OpenCV\lib\libopencv_highgui249.dll.a\ C:\OpenCV\lib\libopencv_imgproc249.dll.a\ C:\OpenCV\lib\libopencv_legacy249.dll.a\ C:\OpenCV\lib\libopencv_ml249.dll.a\ C:\OpenCV\lib\libopencv_nonfree249.dll.a\ C:\OpenCV\lib\libopencv_objdetect249.dll.a\ C:\OpenCV\lib\libopencv_ocl249.dll.a\ C:\OpenCV\lib\libopencv_video249.dll.a\ C:\OpenCV\lib\libopencv_photo249.dll.a\ C:\OpenCV\lib\libopencv_stitching249.dll.a\ C:\OpenCV\lib\libopencv_superres249.dll.a\ C:\OpenCV\lib\libopencv_ts249.a\ C:\OpenCV\lib\libopencv_videostab249.dll.a ~~~ 然后修改main函數,這里設定卷積核的大小均為5*5: ~~~ #include <QCoreApplication> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <QDebug> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // 輸入圖像 cv::Mat image= cv::imread("c:/peng.jpg",0); if (!image.data) return 0; cv::namedWindow("Original Image"); cv::imshow("Original Image",image); // 對圖像進行高斯低通濾波 cv::Mat result; cv::GaussianBlur(image,result,cv::Size(5,5),1.5); cv::namedWindow("Gaussian filtered Image"); cv::imshow("Gaussian filtered Image",result); // 對圖像進行均值濾波 cv::blur(image,result,cv::Size(5,5)); cv::namedWindow("Mean filtered Image"); cv::imshow("Mean filtered Image",result); return a.exec(); } ~~~ 效果: ![](https://box.kancloud.cn/2015-12-30_5683a74fa57b7.jpg) 相比均值濾波,高斯低通濾波的主要不同是引入了加權方案,因為在通常情況下,對于圖像的一個像素,與越靠近的臨近像素有更高的關聯性,因此離中心像素近的像素系數應該比遠處的像素擁有更多的權重。在高斯濾波器中,像素的全重與它離開中心像素點的距離成正比,一維高斯函數可表示為以下形式: ![](https://box.kancloud.cn/2015-12-30_5683a74fbf7de.jpg) 其中,![](https://box.kancloud.cn/2015-12-30_5683a74fccce9.jpg)為歸一化系數,作用是使不同權重之和為1;![](https://box.kancloud.cn/2015-12-30_5683a74fda22a.jpg)稱為西格瑪數值,它的主要作用是控制高斯函數的高度,數值越大則函數越平坦。若要查看高斯濾波器的核,只需選擇合適的西格瑪數值,然后調用函數cv::getGaussianKernel,返回一個ksize*1的數組,該數組的元素滿足高斯公式: ![](https://box.kancloud.cn/2015-12-30_5683a74fe75fa.jpg) 式中的參數分別對應cv::GaussianBlur函數中的參數。以下代碼顯示出核的值,在main函數中添加: ~~~ // 得到高斯核 (西格瑪數值=1.5) cv::Mat gauss= cv::getGaussianKernel(9,1.5,CV_32F); // 顯示高斯核的值 cv::Mat_<float>::const_iterator it= gauss.begin<float>(); cv::Mat_<float>::const_iterator itend= gauss.end<float>(); qDebug() << "["; for ( ; it!= itend; ++it) { qDebug() << *it << " "; } qDebug() << "]"; ~~~ ![](https://box.kancloud.cn/2015-12-30_5683a75003edb.jpg) 若要對一幅圖像使用二維高斯濾波器,根據二維高斯濾波器的可分離特性(即一個二維高斯濾波器可分解為兩個一維高斯濾波器),可以先對圖像的行使用一維高斯濾波器,再對圖像的列使用一維高斯濾波器。在OpenCV中,指定高斯濾波的方法是將系數個數(第三個參數,必須是奇數)以及西格瑪數值![](https://box.kancloud.cn/2015-12-30_5683a74fda22a.jpg)?(第四個參數)提供給cv::GaussianBlur函數。 關于GaussianBlur函數的源碼解析可以參考:[http://www.cnblogs.com/tornadomeet/archive/2012/03/10/2389617.html](http://www.cnblogs.com/tornadomeet/archive/2012/03/10/2389617.html) 以上的均值濾波和高斯低通濾波均屬于線性濾波,此外還存在非線性濾波器,中值濾波器就是最常用的其中一種。與均值濾波、高斯低通濾波相似,它是對一個像素的相鄰區域進行操作以確定像素的值,不同的是中值濾波器僅僅統計這組數組的中值,并用該中值替換中心像素點的值。中值濾波廣泛用于噪聲濾除,以下給出簡單的實現和效果。 首先需要編寫一個簡單的圖像加噪函數,作用是生成若干椒鹽噪聲: ~~~ void salt(cv::Mat& image, int n) // 添加椒鹽噪聲 { for(int k=0; k<n; k++){ int i = rand()%image.cols; int j = rand()%image.rows; if(image.channels() == 1) { if(rand() % 2 == 0) image.at<uchar>(j,i) = 0; else image.at<uchar>(j,i) = 255; }else{ if(rand() % 2 == 0) { image.at<cv::Vec3b>(j,i)[0] = 0; image.at<cv::Vec3b>(j,i)[1] = 0; image.at<cv::Vec3b>(j,i)[2] = 0; } else { image.at<cv::Vec3b>(j,i)[0] = 255; image.at<cv::Vec3b>(j,i)[1] = 255; image.at<cv::Vec3b>(j,i)[2] = 255; } } } } ~~~ 驗證中值濾波法與之前的均值濾波法的效果,修改main函數: ~~~ #include <QCoreApplication> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <QDebug> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // 輸入圖像 image = cv::imread("c:/peng.jpg",0); if (!image.data) return 0; // 給圖像添加椒鹽噪聲 salt(image, 3000); // 顯示加噪圖圖 cv::namedWindow("Salt&Pepper Image"); cv::imshow("Salt&Pepper Image",image); // 對圖像進行均值濾波 cv::blur(image,result,cv::Size(5,5)); cv::namedWindow("Mean filter"); cv::imshow("Mean filter",result); // 對圖像進行中值濾波 cv::medianBlur(image,result,5); cv::namedWindow("Median Filter"); cv::imshow("Median Filter",result); return a.exec(); } ~~~ 效果如下: ![](https://box.kancloud.cn/2015-12-30_5683a75019a8c.jpg) ![](https://box.kancloud.cn/2015-12-30_5683a75041962.png) 可以看到,中值濾波器對于去除椒鹽噪點效果拔群,這是由于一個例外的黑點或白點像素出現在一個相鄰區域時,通常不會被選為中值,因為它們代表的是0或255兩個極端,因此這些噪聲點總會被替換為某個相鄰像素的值,而均值濾波和高斯濾波均會引入噪點信息,噪點處的像素值會極大地影響區域的結果,因此無法很好地濾除這一類噪聲。 由于中值濾波器是非線性的,因此它無法表示為一個核矩陣。此外,中值濾波器還有保留邊緣銳利度的優點。但是缺點是相同區域中的紋理細節也被濾除,如下圖中的樹木部分。 ![](https://box.kancloud.cn/2015-12-30_5683a75066bbf.jpg) **三:高通濾波器** 前面主要介紹了低通濾波器對圖像進行模糊處理,這里進行相反的變換,使用高通濾波器進行圖像銳化或邊緣檢測。Sobel算子就是通過卷積操作來計算圖像的一階導數,由于邊緣處圖像灰度變化率較大,因此可以用sobel算子來進行邊緣檢測。提個簡單的3*3 Sobel算子的核定義為: ![](https://box.kancloud.cn/2015-12-30_5683a750aa0bc.jpg) 如果將圖像視為二維函數,Sobel算子可被認為是在垂直和水平方向變化的測量。這種測量在數學中被成為梯度,通常它被定義為由函數在兩個正交方向上的一階導數組成的二維向量: ![](https://box.kancloud.cn/2015-12-30_5683a750b95f8.jpg) 因此,Sobel算子通過在水平和垂直方向下進行像素差分給出圖像梯度的近似。它在感興趣像素的小窗口內運算,這樣可減少噪聲的影響。OpenCV中提供了函數cv::Sobel使用Sobel核計算圖像卷積的結果,其函數的主要參數如下: ~~~ cv::Sobel(image, // 輸入圖像 sobel, // 輸出圖像 image_depth, // 圖像類型 xorder, yorder, // 核的階數 kernel_size, // 核的大小 alpha,beta); // 縮放值及偏移值 ~~~ 現設計算法,使用Sobel方向濾波器。在main函數中添加: ~~~ cv::Mat image= cv::imread("c:/075.png",0); // 輸入圖像 if (!image.data) return 0; cv::namedWindow("Original Image"); cv::imshow("Original Image",image); // 水平濾波器設置 cv::Mat sobelX; cv::Sobel(image, sobelX, CV_8U, 1, 0, 3, 0.4, 128); cv::namedWindow("Sobel X Image"); cv::imshow("Sobel X Image", sobelX); // 垂直濾波器設置 cv::Mat sobelY; cv::Sobel(image, sobelY, CV_8U, 0, 1, 3, 0.4, 128); cv::namedWindow("Sobel Y Image"); cv::imshow("Sobel Y Image", sobelY); // 計算Sobel范式,濾波器結果保存在16位有符號整數圖像中 cv::Sobel(image, sobelX, CV_16S, 1, 0); cv::Sobel(image, sobelY, CV_16S, 0, 1); cv::Mat sobel; // 將水平和垂直方向相加 sobel = abs(sobelX) + abs(sobelY); // 搜索Sobel的極大值 double sobmin, sobmax; cv::minMaxLoc(sobel, &sobmin, &sobmax); // 將圖像轉換為8位圖像 cv::Mat sobelImage; sobel.convertTo(sobelImage, CV_8U, -255./sobmax, 255); // 輸出圖像 cv::namedWindow("Sobel Image"); cv::imshow("Sobel Image", sobelImage); // 將結果閾值化得到二值圖像 cv::Mat ThresholdedImage; cv::threshold(sobelImage, ThresholdedImage, 225, 255, cv::THRESH_BINARY); cv::namedWindow("Binary Sobel Image"); cv::imshow("Binary Sobel Image",ThresholdedImage); ~~~ 得出水平、垂直方向的邊緣檢測和融合了兩個方向的檢測結果: ![](https://box.kancloud.cn/2015-12-30_5683a750d1c47.jpg) ![](https://box.kancloud.cn/2015-12-30_5683a75133a3b.jpg) Sobel算子是一種經典的邊緣檢測線性濾波器,其主要介紹參考:[http://blog.csdn.net/liyuefeilong/article/details/43452711](http://blog.csdn.net/liyuefeilong/article/details/43452711) 拉普拉斯(Laplacian)是另一種基于圖像導數的高斯線性濾波器,它計算二階導數以衡量圖像的彎曲度。在OpenCV中,使用cv::Laplacian函數來計算,它與cv::Sobel函數相類似。事實上,拉普拉斯與Sobel法都使用同一個函數cv::getDerivkernels來獲取核矩陣。他們的唯一差別是不存在指定導數階數的參數,因為它們都是二階導數。,2D函數的拉普拉斯變換定義如下: ![](https://box.kancloud.cn/2015-12-30_5683a7516cfe2.jpg) 可用一個最簡單的3*3核近似: ![](https://box.kancloud.cn/2015-12-30_5683a7517b7b0.jpg) 與Sobel算子相同,也能夠使用更大的核計算Laplacian,同時由于Laplacian運算對于噪聲十分敏感,我們傾向于這么做(除非計算效率更重要)。需要注意Laplacian核的總數為0,這保證了強度不變區域的Laplacian為0。事實上,由于Laplacian度量的是圖像函數的曲率,它在平坦區域應該等于0。 拉普拉斯算子的效果可能很難解釋。從核的定義來看,很明顯,任何孤立的像素值(它與相鄰像素值截然不同)將被算子放大。這源于算子對噪點的高靈敏度。但是拉普拉斯算子值在圖像邊緣處的表現更有趣。邊緣的存在是圖像中不同灰度區域間快速過渡的結果。沿著圖像在一條邊上的變化(例如,從暗處到亮處),可以觀察到灰度的提升意味著從正曲率(強度值開始上升)到負曲率(當強度即將達到最高至)的漸變。因此,正、負拉普拉斯算子值(或導數)之間的過渡是存在邊緣的指示器。另一種表達這個事實的方法是說,邊緣位于Laplacian函數的零交叉點。 下圖是取一幅圖像中的一個觀測窗口進行放大得出的個像素點的像素值,可以看到沿著Laplacian的零交叉點,就可以得到一條對應于圖像窗口中可見的邊緣曲線。 ![](https://box.kancloud.cn/2015-12-30_5683a7518c869.jpg) 然而,跟隨Laplacian圖像中零交叉曲線是一件容易出錯的事,因此在以下程序中將給出一個簡化的算法用于檢測近似的零交叉位置,即函數: ~~~ cv::Mat getZeroCrossings(float threshold = 1.0); cv::Mat getZeroCrossingsWithSobel(float threshold); ~~~ 大致的掃描過程是,比較當前像素與左側像素,如果兩者符號不同,那么說明當前像素存在零交叉。如果沒有,在正上方位置重復相同的測試。在第二個函數中,還引入Sobel算子來得到零點交叉的二值圖像,以下給出Laplacian變換算法的實現過程。 首先,創建一個類Laplacian來實現一些與拉普拉斯變換有關的操作,先在Laplacian.h中添加: ~~~ #ifndef LAPLACIAN_H #define LAPLACIAN_H #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> class Laplacian { public: Laplacian():aperture(3){} // 設置卷積核的大小 void setAperture(int a); // 計算浮點Laplacian cv::Mat calcLaplacian(const cv::Mat &image); // 返回8位圖像存儲的Laplacian結果 cv::Mat getLaplacianImage(double scale = -1.0); // 以下函數可得到零點交叉的二值圖像 cv::Mat getZeroCrossings(float threshold = 1.0); cv::Mat getZeroCrossingsWithSobel(float threshold); private: cv::Mat img; // 原圖像 cv::Mat laplace; // 包含Laplacian的32位浮點圖像 int aperture; // 卷積核的大小 }; #endif // LAPLACIAN_H ~~~ 接著在Laplacian.cpp中定義各個函數: ~~~ #include "laplacian.h" #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> // 設置卷積核的大小 void Laplacian::setAperture(int a) { aperture = a; } // 計算浮點Laplacian cv::Mat Laplacian::calcLaplacian(const cv::Mat &image) { // 計算Laplacian cv::Laplacian(image, laplace, CV_32F, aperture); // 保留圖像的局部備份(用于零點交叉) img = image.clone(); return laplace; } // 返回8位圖像存儲的Laplacian結果 // 零點交叉于灰度值128 // 如果沒有指定scale參數,則最大值縮放至強度255 // 必須在調用它之前調用calcLaplacian() cv::Mat Laplacian::getLaplacianImage(double scale) { if (scale<0) { double lapmin, lapmax; cv::minMaxLoc(laplace,&lapmin,&lapmax); scale= 127/ std::max(-lapmin,lapmax); } cv::Mat laplaceImage; laplace.convertTo(laplaceImage,CV_8U,scale,128); return laplaceImage; } // 得到零點交叉的二值圖像 // 如果相鄰像素的乘積小于threshold // 則零點交叉被忽略 cv::Mat Laplacian::getZeroCrossings(float threshold) { // 創建迭代器 cv::Mat_<float>::const_iterator it= laplace.begin<float>()+laplace.step1(); cv::Mat_<float>::const_iterator itend= laplace.end<float>(); cv::Mat_<float>::const_iterator itup= laplace.begin<float>(); // 初始化為白色的二值圖像 cv::Mat binary(laplace.size(),CV_8U,cv::Scalar(255)); cv::Mat_<uchar>::iterator itout= binary.begin<uchar>()+binary.step1(); // 對輸入閾值取反 threshold *= -1.0; for ( ; it!= itend; ++it, ++itup, ++itout) { // 如果相鄰像素的乘積為負數,則符號發生改變 if (*it * *(it-1) < threshold) *itout= 0; // 水平方向零點交叉 else if (*it * *itup < threshold) *itout= 0; // 垂直方向零點交叉 } return binary; } // 使用sobel算子得到零點交叉的二值圖像 // 如果相鄰的像素的乘積小雨threshold // 那么零點交叉將被忽略 cv::Mat Laplacian::getZeroCrossingsWithSobel(float threshold) { cv::Mat sx; cv::Sobel(img,sx,CV_32F,1,0,1); cv::Mat sy; cv::Sobel(img,sy,CV_32F,0,1,1); // 創建迭代器 cv::Mat_<float>::const_iterator it= laplace.begin<float>()+laplace.step1(); cv::Mat_<float>::const_iterator itend= laplace.end<float>(); cv::Mat_<float>::const_iterator itup= laplace.begin<float>(); cv::Mat_<float>::const_iterator itx= sx.begin<float>()+sx.step1(); cv::Mat_<float>::const_iterator ity= sy.begin<float>()+sy.step1(); // 初始化為白色的二值圖像 cv::Mat binary(laplace.size(),CV_8U,cv::Scalar(255)); cv::Mat_<uchar>::iterator itout= binary.begin<uchar>()+binary.step1(); for ( ; it!= itend; ++it, ++itup, ++itout, ++itx, ++ity) { // 如果相鄰像素的乘積為負數,則符號發生改變 if (*it * *(it-1) < 0.0 && fabs(*ity) > threshold) *itout= 0; // 水平方向零點交叉 else if (*it * *itup < 0.0 && fabs(*ity) > threshold) *itout= 0; // 垂直方向零點交叉 } return binary; } ~~~ 最后修改main函數: ~~~ #include <QCoreApplication> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <QDebug> #include "laplacian.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); cv::Mat image= cv::imread("c:/073.jpg",0); // 輸入圖像 if (!image.data) return 0; // 顯示包含感興趣區域的灰度化原圖像 cv::rectangle(image,cv::Point(362,135),cv::Point(374,147),cv::Scalar(255,255,255)); cv::namedWindow("Original Image with ROI"); cv::imshow("Original Image with ROI",image); // 直接調用函數進行7*7的拉普拉斯變換 cv::Mat laplace; cv::Laplacian(image,laplace,CV_8U,7,0.01,128); cv::namedWindow("Laplacian Image"); cv::imshow("Laplacian Image",laplace); // 使用自建類Laplacian實現拉普拉斯變換 Laplacian laplacian; laplacian.setAperture(7); cv::Mat flap= laplacian.calcLaplacian(image); double lapmin, lapmax; cv::minMaxLoc(flap,&lapmin,&lapmax); laplace = laplacian.getLaplacianImage(); cv::namedWindow("Laplacian Image (7x7)"); cv::imshow("Laplacian Image (7x7)",laplace); // 顯示零點交叉 cv::Mat zeros; zeros= laplacian.getZeroCrossings(lapmax); cv::namedWindow("Zero-crossings"); cv::imshow("Zero-crossings",zeros); // 使用Sobel算子顯示零點交叉 zeros= laplacian.getZeroCrossings(); zeros= laplacian.getZeroCrossingsWithSobel(50); cv::namedWindow("Zero-crossings (2)"); return a.exec(); } ~~~ 調用函數(左)、使用自建類實現7*7拉普拉斯變換的效果對比: ![](https://box.kancloud.cn/2015-12-30_5683a751ac564.jpg) 輸出零點交叉檢測到的所有邊緣,由于Laplacian不對強邊與弱邊作區分,且對噪聲十分敏感,因此輸出結果檢測到很多的邊緣。 ![](https://box.kancloud.cn/2015-12-30_5683a75211deb.jpg)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看