国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

OpenCV15-圖像邊緣檢測(cè):Sobel、Scharr、Laplace、Canny

這篇具有很好參考價(jià)值的文章主要介紹了OpenCV15-圖像邊緣檢測(cè):Sobel、Scharr、Laplace、Canny。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。


1.邊緣檢測(cè)原理

圖像的邊緣指的是圖像中像素灰度值突然發(fā)生變化的區(qū)域,如果將圖像中的每一行像素和每一列像素都描述成一個(gè)關(guān)于灰度值的函數(shù),那么圖像的邊緣對(duì)應(yīng)在灰度值函數(shù)中是函數(shù)值突然變大的區(qū)域。函數(shù)值得變化趨勢(shì)可以用導(dǎo)數(shù)描述,當(dāng)函數(shù)值突然變大時(shí),導(dǎo)數(shù)也必然會(huì)變大,而函數(shù)值變化較為平緩時(shí),導(dǎo)數(shù)值也比較小,因此可以通過(guò)尋找導(dǎo)數(shù)值較大的區(qū)域?qū)ふ液瘮?shù)中突然變化的區(qū)域,進(jìn)而確定圖像中的邊緣位置。

由于圖像是練得信號(hào),因此我們可以用臨近的兩個(gè)像素值來(lái)表示像素灰度值函數(shù)的導(dǎo)數(shù),求導(dǎo)形式表示如下:
d f ( x , y ) d x = f ( x , y ) ? f ( x ? 1 , y ) \frac{df(x,y)}{dx} = f(x,y) - f(x-1,y) dxdf(x,y)?=f(x,y)?f(x?1,y)
這種對(duì)x軸方向的濾波器為 [ ? 1 1 ] \begin{bmatrix} -1 & 1 \end{bmatrix} [?1?1?],同樣對(duì)y軸方向的求導(dǎo)對(duì)應(yīng)的濾波器為 [ ? 1 1 ] T \begin{bmatrix} -1 & 1 \end{bmatrix}^T [?1?1?]T 。

而表示某個(gè)像素處的梯度,最接近的方式是求取前一個(gè)像素和后一個(gè)像素的差值,于是修改上式為:
d f ( x , y ) d x = f ( x + 1 , y ) ? f ( x ? 1 , y ) 2 \frac{df(x,y)}{dx} = \frac{f(x+1,y) - f(x-1,y)}{2} dxdf(x,y)?=2f(x+1,y)?f(x?1,y)?
改進(jìn)的求導(dǎo)方式對(duì)應(yīng)的濾波器在 X 方向和 Y 方向分別為 [ ? 0.5 0 0.5 ] \begin{bmatrix} -0.5 & 0 & 0.5 \end{bmatrix} [?0.5?0?0.5?] [ ? 0.5 0 0.5 ] T \begin{bmatrix} -0.5 & 0 & 0.5 \end{bmatrix}^T [?0.5?0?0.5?]T 。

根據(jù)這種方式,也可以使用下面的濾波器計(jì)算 4 5 ° 45^\circ 45° 方向的梯度:

X Y = [ 1 0 0 ? 1 ] Y X = [ 0 1 ? 1 0 ] XY = \begin{bmatrix} 1 & 0 \\ 0 & -1 \\ \end{bmatrix} YX = \begin{bmatrix} 0 & 1 \\ -1 & 0 \\ \end{bmatrix} XY=[10?0?1?]YX=[0?1?10?]

圖像的邊緣有可能是由高像素值變?yōu)榈拖袼刂?,也有可能是由低像素值變成高像素值。通過(guò)上面的梯度公式,得到正數(shù)值表示像素值突然由低變高,得到的負(fù)數(shù)值表示像素值由高到低,這兩種都是圖像的邊緣,因此,為了在圖像中同時(shí)表示出這兩種邊緣信息,需要將計(jì)算的結(jié)果求取絕對(duì)值。

OpenCV中提供了 convertScaleAbs() 函數(shù)用于計(jì)算矩陣中的所有數(shù)據(jù)的的絕對(duì)值:

void convertScaleAbs(
    InputArray src,    // 輸入圖像
    OutputArray dst,   // 輸出圖像
    double alpha = 1,  // 縮放因子
    double beta = 0    // 偏置值
);

下面代碼中給出了利用 filter2D() 函數(shù)實(shí)現(xiàn)圖像邊緣檢測(cè)的算法,需要說(shuō)明的是,由于求取邊緣的結(jié)果可能會(huì)有負(fù)值,不在原始圖像的 CV_8U 數(shù)據(jù)范圍內(nèi),因此濾波后的圖像數(shù)據(jù)類型不要用 “-1” ,而應(yīng)該為 CV_16S。

#include <opencv2\opencv.hpp>
#include <opencv2/core/utils/logger.hpp> // debug no log

using namespace cv;
using namespace std;

int main()
{
	cout << "OpenCV Version: " << CV_VERSION << endl;
	utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);

	//創(chuàng)建邊緣檢測(cè)濾波器
	Mat kernel1 = (Mat_<float>(1, 2) << 1, -1);  //X方向邊緣檢測(cè)濾波器
	Mat kernel2 = (Mat_<float>(1, 3) << 1, 0, -1);  //X方向邊緣檢測(cè)濾波器
	Mat kernel3 = (Mat_<float>(3, 1) << 1, 0, -1);  //X方向邊緣檢測(cè)濾波器
	Mat kernelXY = (Mat_<float>(2, 2) << 1, 0, 0, -1);  //由左上到右下方向邊緣檢測(cè)濾波器
	Mat kernelYX = (Mat_<float>(2, 2) << 0, -1, 1, 0);  //由右上到左下方向邊緣檢測(cè)濾波器

	//讀取圖像,黑白圖像邊緣檢測(cè)結(jié)果較為明顯
	Mat img = imread("equalLena.png", IMREAD_ANYCOLOR);
	if (img.empty())
	{
		cout << "請(qǐng)確認(rèn)圖像文件名稱是否正確" << endl;
		return -1;
	}
	Mat result1, result2, result3, result4, result5, result6;

	//檢測(cè)圖像邊緣
	//以[1 -1]檢測(cè)水平方向邊緣
	filter2D(img, result1, CV_16S, kernel1);
	convertScaleAbs(result1, result1);

	//以[1 0 -1]檢測(cè)水平方向邊緣
	filter2D(img, result2, CV_16S, kernel2);
	convertScaleAbs(result2, result2);

	//以[1 0 -1]'檢測(cè)由垂直方向邊緣
	filter2D(img, result3, CV_16S, kernel3);
	convertScaleAbs(result3, result3);

	//整幅圖像的邊緣
	result6 = result2 + result3;
	//檢測(cè)由左上到右下方向邊緣
	filter2D(img, result4, CV_16S, kernelXY);
	convertScaleAbs(result4, result4);

	//檢測(cè)由右上到左下方向邊緣
	filter2D(img, result5, CV_16S, kernelYX);
	convertScaleAbs(result5, result5);

	//顯示邊緣檢測(cè)結(jié)果
	imshow("result1", result1);
	imshow("result2", result2);
	imshow("result3", result3);
	imshow("result4", result4);
	imshow("result5", result5);
	imshow("result6", result6);

	waitKey(0);
	return 0;
}

2.Sobel算子

使用Sobel邊緣檢測(cè)算子提取圖像邊緣的過(guò)程:

1.提取 X 方向的邊緣,X方向的一階 Sobel 邊緣檢測(cè)算子:
[ ? 1 0 1 ? 2 0 2 ? 1 0 1 ] \begin{bmatrix} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1 \\ \end{bmatrix} ??1?2?1?000?121? ?
2.提取 Y 方向的邊緣,Y方向的一階 Sobel 邊緣檢測(cè)算子:
[ ? 1 ? 2 ? 1 0 0 0 1 2 1 ] \begin{bmatrix} -1 & -2 & -1 \\ 0 & 0 & 0 \\ 1 & 2 & 1 \\ \end{bmatrix} ??101??202??101? ?
3.綜合兩個(gè)方向的邊緣信息得到整幅圖像的邊緣。由兩個(gè)方向的邊緣得到整幅圖像的邊緣有兩種計(jì)算方式,第一種是求取兩幅圖像對(duì)應(yīng)像素的像素值的絕對(duì)值之和,第二種是求取兩幅圖像對(duì)應(yīng)像素值的平方和的二次方根:
I ( x , y ) = I x ( x , y ) 2 + I y ( x , y ) 2 I ( x , y ) = ∣ I x ( x , y ) ∣ + ∣ I y ( x , y ) ∣ \begin{align} I(x,y) &= \sqrt{I_x(x,y)^2 + I_y(x,y)^2} \\ I(x,y) &= |I_x(x,y)| + |I_y(x,y)| \\ \end{align} I(x,y)I(x,y)?=Ix?(x,y)2+Iy?(x,y)2 ?=Ix?(x,y)+Iy?(x,y)??
OpenCV提供了對(duì)圖像提取 Sobel 邊緣的 Sobel() 函數(shù):

void Sobel(
    InputArray src, 
    OutputArray dst, 
    int ddepth, // 輸出圖像的數(shù)據(jù)類型,-1表示自動(dòng)選擇
    int dx, // X方向差分階數(shù),即使用幾階Sobel算子
    int dy, // Y方向差分階數(shù),即使用幾階Sobel算子
    int ksize = 3, // Sobel算子尺寸,必須是1,3,5,7
    double scale = 1, // 對(duì)導(dǎo)數(shù)計(jì)算結(jié)果進(jìn)行縮放
    double delta = 0, // 偏置值
    int borderType = BORDER_DEFAULT
);

dx、dy、ksize:任意一個(gè)方向的差分階數(shù)都需要小于算子的尺寸。但有以下特殊情況:當(dāng)ksize=1時(shí),任意一個(gè)方向的階數(shù)都需要小于3。

一般情況下,當(dāng)差分階數(shù)的最大值取1時(shí),ksize取3;當(dāng)差分階數(shù)的最大值取2時(shí),ksize取5;當(dāng)差分階數(shù)的最大值取3時(shí),ksize取7;

當(dāng)ksize=1時(shí),程序中使用的算子尺寸不再是正方形,而是3x1或者1x3。

#include <opencv2\opencv.hpp>
#include <opencv2/core/utils/logger.hpp> // debug no log

using namespace cv;
using namespace std;

int main()
{
	cout << "OpenCV Version: " << CV_VERSION << endl;
	utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);

	//讀取圖像,黑白圖像邊緣檢測(cè)結(jié)果較為明顯
	Mat img = imread("equalLena.png", IMREAD_ANYCOLOR);
	if (img.empty())
	{
		cout << "請(qǐng)確認(rèn)圖像文件名稱是否正確" << endl;
		return -1;
	}
	Mat resultX, resultY, resultXY;

	//X方向一階邊緣
	Sobel(img, resultX, CV_16S, 1, 0, 1);
	convertScaleAbs(resultX, resultX);

	//Y方向一階邊緣
	Sobel(img, resultY, CV_16S, 0, 1, 3);
	convertScaleAbs(resultY, resultY);

	//整幅圖像的一階邊緣
	resultXY = resultX + resultY;

	//顯示圖像
	imshow("resultX", resultX);
	imshow("resultY", resultY);
	imshow("resultXY", resultXY);

	waitKey(0);
	return 0;
}

3.Scharr算子

雖然Sobel算子可以有效地提取圖像邊緣,但是對(duì)于圖像中較弱的邊緣提取效果較差。因此,為了能夠有效地提出較弱的邊緣,需要將像素值間的差距值增大。

Socharr算子是對(duì)Sobel算子差異性的增強(qiáng),兩者在檢測(cè)圖像邊緣的原理和使用方式上相同,Scharr算子在X方向和Y方向的邊緣檢測(cè)算子:
G x = [ ? 3 0 3 ? 10 0 10 ? 3 0 3 ] G y = [ ? 3 ? 10 ? 3 0 0 0 3 10 3 ] G_x = \begin{bmatrix} -3 & 0 & 3 \\ -10 & 0 & 10 \\ -3 & 0 & 3 \\ \end{bmatrix} G_y = \begin{bmatrix} -3 & -10 & -3 \\ 0 & 0 & 0 \\ 3 & 10 & 3 \\ \end{bmatrix} Gx?= ??3?10?3?000?3103? ?Gy?= ??303??10010??303? ?
OpenCV提供了對(duì)圖像提取Scharr邊緣的 Scharr() 函數(shù):

void Scharr(
    InputArray src, 
    OutputArray dst, 
    int ddepth,
    int dx, 
    int dy, 
    double scale = 1, 
    double delta = 0,
    int borderType = BORDER_DEFAULT
);

dx和dy只能有一個(gè)為1,并且不能同時(shí)為0。

下面代碼中,分別提取X方向和Y方向邊緣,并利用這兩個(gè)方向的邊緣求取整幅圖像的邊緣。可以看出Scharr算子比Sobel算子提取到更微弱的邊緣。

#include <opencv2\opencv.hpp>
#include <opencv2/core/utils/logger.hpp> // debug no log

using namespace cv;
using namespace std;

int main()
{
	cout << "OpenCV Version: " << CV_VERSION << endl;
	utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);

	//讀取圖像,黑白圖像邊緣檢測(cè)結(jié)果較為明顯
	Mat img = imread("equalLena.png", IMREAD_ANYDEPTH);
	if (img.empty())
	{
		cout << "請(qǐng)確認(rèn)圖像文件名稱是否正確" << endl;
		return -1;
	}
	Mat resultX, resultY, resultXY;

	//X方向一階邊緣
	Scharr(img, resultX, CV_16S, 1, 0);
	convertScaleAbs(resultX, resultX);

	//Y方向一階邊緣
	Scharr(img, resultY, CV_16S, 0, 1);
	convertScaleAbs(resultY, resultY);

	//整幅圖像的一階邊緣
	resultXY = resultX + resultY;

	//顯示圖像
	imshow("resultX", resultX);
	imshow("resultY", resultY);
	imshow("resultXY", resultXY);

	waitKey(0);
	return 0;
}

4.生成邊緣檢測(cè)濾波器

Scharr算子只有上面的兩種,而Sobel算子有不同的尺寸、不同階數(shù)。OpenCV中提供了 getDerivKernels() 函數(shù)可以得到不同尺寸、不同階數(shù)的Sobel算子和Scharr算子濾波器。

void getDerivKernels(
    OutputArray kx, // 行濾波器系數(shù)輸出矩陣 ksize x 1
    OutputArray ky, // 列濾波器系數(shù)輸出矩陣 ksize x 1 
    int dx,     // X方向?qū)?shù)的階次
    int dy,     // Y方向?qū)?shù)的階次
    int ksize,  // 濾波器的大小可以為FILTER_SCHARR、1、3、5、7
    bool normalize = false, // 是否歸一化
    int ktype = CV_32F      // 濾波器系數(shù)類型,CV_32F、CV_64F
);

下面的例子中給出利用 getDerivKernels() 函數(shù)生成Sobel算子和Scharr算子的代碼:

#include <opencv2\opencv.hpp>
#include <opencv2/core/utils/logger.hpp> // debug no log

using namespace cv;
using namespace std;

int main()
{
	cout << "OpenCV Version: " << CV_VERSION << endl;
	utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);

	Mat sobel_x1, sobel_y1, sobel_x2, sobel_y2, sobel_x3, sobel_y3;  //存放分離的Sobel算子
	Mat scharr_x, scharr_y;  //存放分離的Scharr算子
	Mat sobelX1, sobelX2, sobelX3, scharrX;  //存放最終算子

	//一階X方向Sobel算子
	getDerivKernels(sobel_x1, sobel_y1, 1, 0, 3);
	sobel_x1 = sobel_x1.reshape(CV_8U, 1);
	sobelX1 = sobel_y1 * sobel_x1;  //計(jì)算濾波器

	//二階X方向Sobel算子
	getDerivKernels(sobel_x2, sobel_y2, 2, 0, 5);
	sobel_x2 = sobel_x2.reshape(CV_8U, 1);
	sobelX2 = sobel_y2 * sobel_x2;  //計(jì)算濾波器

	//三階X方向Sobel算子
	getDerivKernels(sobel_x3, sobel_y3, 3, 0, 7);
	sobel_x3 = sobel_x3.reshape(CV_8U, 1);
	sobelX3 = sobel_y3 * sobel_x3;  //計(jì)算濾波器

	//X方向Scharr算子
	getDerivKernels(scharr_x, scharr_y, 1, 0, FILTER_SCHARR);
	scharr_x = scharr_x.reshape(CV_8U, 1);
	scharrX = scharr_y * scharr_x;  //計(jì)算濾波器

	//輸出結(jié)果
	cout << "X方向一階Sobel算子:" << endl << sobelX1 << endl;
	cout << "X方向二階Sobel算子:" << endl << sobelX2 << endl;
	cout << "X方向三階Sobel算子:" << endl << sobelX3 << endl;
	cout << "X方向Scharr算子:" << endl << scharrX << endl;

	waitKey(0);
	return 0;
}
/*
X方向一階Sobel算子:
[-1, 0, 1;
 -2, 0, 2;
 -1, 0, 1]
X方向二階Sobel算子:
[1, 0, -2, 0, 1;
 4, 0, -8, 0, 4;
 6, 0, -12, 0, 6;
 4, 0, -8, 0, 4;
 1, 0, -2, 0, 1]
X方向三階Sobel算子:
[-1, 0, 3, 0, -3, 0, 1;
 -6, 0, 18, 0, -18, 0, 6;
 -15, 0, 45, 0, -45, 0, 15;
 -20, 0, 60, 0, -60, 0, 20;
 -15, 0, 45, 0, -45, 0, 15;
 -6, 0, 18, 0, -18, 0, 6;
 -1, 0, 3, 0, -3, 0, 1]
X方向Scharr算子:
[-3, 0, 3;
 -10, 0, 10;
 -3, 0, 3]
*/

5.Laplacian算子

上述的邊緣檢測(cè)算子都具有方向性,因此都需要分別求取X方向的邊緣和Y方向的邊緣,之后將兩個(gè)方向的邊緣綜合得到圖像的整體邊緣。Laplacian算子具有各個(gè)方向同性的特點(diǎn),能夠?qū)θ我夥较虻倪吘夁M(jìn)行提取,具有無(wú)方向性的優(yōu)點(diǎn)。

Laplacian算子是一種二階導(dǎo)數(shù)算子,對(duì)噪聲比較敏感,因此常需要配合高斯濾波一起使用。

二維圖像函數(shù) f ( x , y ) f(x,y) f(x,y) ,圖像的Laplace運(yùn)算二階導(dǎo)數(shù)定義:
? 2 f ( x , y ) = ? 2 f ? x 2 + ? 2 f ? y 2 \nabla^2 f(x,y) = \frac{\partial^2 f}{\partial x^2} + \frac{\partial^2 f}{\partial y^2} ?2f(x,y)=?x2?2f?+?y2?2f?
對(duì)于二維離散圖像而言,圖像的Laplace可表示吐下:
? 2 f ( x , y ) = f ( x + 1 , y ) + f ( x ? 1 , y ) + f ( x , y + 1 ) + f ( x , y ? 1 ) ? 4 f ( x , y ) \nabla^2 f(x,y) = f(x+1,y) + f(x-1,y) + f(x,y+1) + f(x,y-1) - 4f(x,y) ?2f(x,y)=f(x+1,y)+f(x?1,y)+f(x,y+1)+f(x,y?1)?4f(x,y)
根據(jù)離散Laplace表達(dá)式,可以得到其濾波器:
G 1 = [ 0 1 0 1 ? 4 1 0 1 0 ] G 2 = [ 1 1 1 1 ? 8 1 1 1 1 ] G_1 = \begin{bmatrix} 0 & 1 & 0 \\ 1 & -4 & 1 \\ 0 & 1 & 0 \\ \end{bmatrix} G_2 = \begin{bmatrix} 1 & 1 & 1 \\ 1 & -8 & 1 \\ 1 & 1 & 1 \\ \end{bmatrix} G1?= ?010?1?41?010? ?G2?= ?111?1?81?111? ?
G 1 G_1 G1? G 2 G_2 G2? 分別為離散拉普拉斯算子的模版與拓展模版,利用函數(shù)模版可以將圖像中的奇異點(diǎn)如亮點(diǎn)變得更亮。對(duì)于圖像中灰度變化劇烈的區(qū)域,拉普拉斯算子能實(shí)現(xiàn)其邊緣檢測(cè)。

OpenCV提供了Laplacian算子提取圖像邊緣的 Laplacian() 函數(shù):

void Laplacian(
    InputArray src,
    OutputArray dst, 
    int ddepth,
    int ksize = 1,    // 濾波器大小,必須為正奇數(shù)
    double scale = 1, 
    double delta = 0,
    int borderType = BORDER_DEFAULT
);

ksize=1時(shí),采用 G 1 G_1 G1? 拉普拉斯算子。

下面代碼中,采用圖像去噪后通過(guò)拉普拉斯算子提取邊緣變得更加準(zhǔn)確:

#include <opencv2\opencv.hpp>
#include <opencv2/core/utils/logger.hpp> // debug no log

using namespace cv;
using namespace std;

int main()
{
	cout << "OpenCV Version: " << CV_VERSION << endl;
	utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);

	//讀取圖像,黑白圖像邊緣檢測(cè)結(jié)果較為明顯
	Mat img = imread("equalLena.png", IMREAD_ANYDEPTH);
	if (img.empty())
	{
		cout << "請(qǐng)確認(rèn)圖像文件名稱是否正確" << endl;
		return -1;
	}
	Mat result, result_g, result_G;

	//未濾波提取邊緣
	Laplacian(img, result, CV_16S, 3, 1, 0);
	convertScaleAbs(result, result);

	//濾波后提取Laplacian邊緣
	GaussianBlur(img, result_g, Size(3, 3), 5, 0);  //高斯濾波
	Laplacian(result_g, result_G, CV_16S, 3, 1, 0);
	convertScaleAbs(result_G, result_G);

	//顯示圖像
	imshow("result", result);
	imshow("result_G", result_G);

	waitKey(0);
	return 0;
}

6.Canny算法

Canny算法不容易受到噪聲的影響,能夠識(shí)別圖像中的若邊緣和強(qiáng)邊緣,并結(jié)合強(qiáng)弱邊緣的位置關(guān)系,綜合給出圖像整體的邊緣信息。Canny邊緣檢測(cè)算法是目前最優(yōu)越的邊緣檢測(cè)算法之一。該方法的檢測(cè)過(guò)程:

1.使用高斯濾波去噪,平滑圖像,下面是5x5的高斯濾波器:
G = 1 139 [ 2 4 5 4 2 4 9 12 9 4 5 12 15 12 5 4 9 12 9 4 2 4 5 4 2 ] G = \frac{1}{139} \begin{bmatrix} 2 & 4 & 5 & 4 & 2 \\ 4 & 9 & 12 & 9 & 4 \\ 5 & 12 & 15 & 12 & 5 \\ 4 & 9 & 12 & 9 & 4 \\ 2 & 4 & 5 & 4 & 2 \\ \end{bmatrix} G=1391? ?24542?491294?51215125?491294?24542? ?
2.計(jì)算圖像中每個(gè)像素的梯度幅值與方向。可以通過(guò)Sobel算子分別檢測(cè)圖像X方向和Y方向邊緣,之后利用下面公式計(jì)算梯度的方向和幅值:
θ = a r c t a n ( I y I x ) G = a r c t a n I x 2 + I y 2 \theta = arctan(\frac{I_y}{I_x}) \\ G = arctan\sqrt{I_x^2 + I_y^2} θ=arctan(Ix?Iy??)G=arctanIx2?+Iy2? ?
其中梯度方向近似到下面4個(gè)取值: 0 ° 0^\circ 0°、 4 5 ° 45^\circ 45°、 9 0 ° 90^\circ 90° 13 5 ° 135^\circ 135°

3.利用非極大值抑制算法消除邊緣檢測(cè)帶來(lái)的雜散響應(yīng)。通俗意義上是指尋找像素點(diǎn)局部最大值,將非極大值點(diǎn)所對(duì)應(yīng)的灰度值設(shè)置為背景像素點(diǎn),如像素領(lǐng)域區(qū)域滿足梯度值的局部最優(yōu)值判斷為該像素的邊緣,對(duì)其余非極大值的相關(guān)信息進(jìn)行抑制。

4.應(yīng)用雙閾值法劃分強(qiáng)邊緣和弱邊緣。如果某一像素位置的幅值超過(guò)高閾值,該像素被保留為邊緣;如果某一像素位置的幅值小于低閾值,該像素被排除;如果某一像素位置的幅值在兩個(gè)閾值之間,該像素僅僅在連接到一個(gè)高于閾值的像素時(shí)被保留。推薦高與低閾值比在 2:13:1 之間。

Canny算法流程復(fù)雜,好在OpenCV中提供了 Canny() 函數(shù)實(shí)現(xiàn)Canny算法檢測(cè)圖像中的邊緣:

void Canny(
    InputArray image,  // CV_8U
    OutputArray edges, 
    double threshold1, // 第一個(gè)滯后閾值
    double threshold2, // 第二個(gè)滯后閾值
    int apertureSize = 3,   // Sobel算子直徑
    bool L2gradient = false // 計(jì)算圖像梯度幅值的方法是否使用L2范數(shù)
);

下面的代碼中,通過(guò)設(shè)置不同的閾值來(lái)比較閾值的大小對(duì)圖像邊緣檢測(cè)效果的影響,可以發(fā)現(xiàn),較高的閾值會(huì)降低噪聲信息的影響,但是也會(huì)減少邊緣信息。

#include <opencv2\opencv.hpp>
#include <opencv2/core/utils/logger.hpp> // debug no log

using namespace cv;
using namespace std;

int main()
{
	cout << "OpenCV Version: " << CV_VERSION << endl;
	utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);

	//讀取圖像,黑白圖像邊緣檢測(cè)結(jié)果較為明顯
	Mat img = imread("equalLena.png", IMREAD_ANYDEPTH);
	if (img.empty())
	{
		cout << "請(qǐng)確認(rèn)圖像文件名稱是否正確" << endl;
		return -1;
	}
	Mat resultHigh, resultLow, resultG;

	//大閾值檢測(cè)圖像邊緣
	Canny(img, resultHigh, 100, 200, 3);

	//小閾值檢測(cè)圖像邊緣
	Canny(img, resultLow, 20, 40, 3);

	//高斯模糊后檢測(cè)圖像邊緣
	GaussianBlur(img, resultG, Size(3, 3), 5);
	Canny(resultG, resultG, 100, 200, 3);

	//顯示圖像
	imshow("resultHigh", resultHigh);
	imshow("resultLow", resultLow);
	imshow("resultG", resultG);

	waitKey(0);
	return 0;
}

OpenCV15-圖像邊緣檢測(cè):Sobel、Scharr、Laplace、Canny,OpenCV,opencv,計(jì)算機(jī)視覺(jué),c++文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-721885.html

到了這里,關(guān)于OpenCV15-圖像邊緣檢測(cè):Sobel、Scharr、Laplace、Canny的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 使用c++視覺(jué)處理----canny 邊緣檢測(cè)、sobel邊緣檢測(cè)、scharr 濾波邊緣檢測(cè)
  • Python邊緣檢測(cè)之prewitt, sobel, laplace算子

    Python邊緣檢測(cè)之prewitt, sobel, laplace算子

    ndimage 中提供了卷積算法,并且建立在卷積之上,提供了三種邊緣檢測(cè)的濾波方案: prewitt , sobel 以及 laplace 。 在convolve中列舉了一個(gè)用于邊緣檢測(cè)的濾波算子,統(tǒng)一維度后,其 x x x 和 y y y 向的梯度算子分別寫為 [ ? 1 0 1 ? 1 0 1 ? 1 0 1 ] , [ ? 1 ? 1 ? 1 0 0 0 1 1 1 ] begin{bma

    2024年02月03日
    瀏覽(23)
  • Halcon邊緣檢測(cè)Sobel、Laplace和Canny算子

    Halcon邊緣檢測(cè)Sobel、Laplace和Canny算子

    提示:文章參考了網(wǎng)絡(luò)上其他作者的文章,以及相關(guān)書籍,如有侵權(quán),請(qǐng)聯(lián)系作者。 ???????除了閾值分割外,也可以通過(guò)檢測(cè)區(qū)域的邊緣得到目標(biāo)區(qū)域。區(qū)域的邊緣像素的灰度值往往會(huì)發(fā)生灰度上的突變,針對(duì)這些跳躍性的突變進(jìn)行檢測(cè)和計(jì)算,可以得到區(qū)域的邊緣輪廓

    2023年04月08日
    瀏覽(21)
  • Halcon經(jīng)典的邊緣檢測(cè)算子Sobel/Laplace/Canny

    關(guān)于邊緣檢測(cè),有許多經(jīng)典的算子,各大圖形處理庫(kù)都有各自的邊緣檢測(cè)算子,這里簡(jiǎn)要介紹幾種。 Sobel算子結(jié)合了高斯平滑和微分求導(dǎo)。它是一階導(dǎo)數(shù)的邊緣檢測(cè)算子,使用卷積核對(duì)圖像中的每個(gè)像素點(diǎn)做卷積和運(yùn)算,然后采用合適的閾值提取邊緣。Soble算子有兩個(gè)卷積核

    2024年01月22日
    瀏覽(21)
  • opencv基礎(chǔ)41-圖像梯度-sobel算子詳解cv2.Sobel()(邊緣檢測(cè)基礎(chǔ))

    opencv基礎(chǔ)41-圖像梯度-sobel算子詳解cv2.Sobel()(邊緣檢測(cè)基礎(chǔ))

    圖像梯度是用于描述圖像變化率的概念。在圖像處理中,梯度指的是圖像中每個(gè)像素的灰度值變化速率或方向。它常用于邊緣檢測(cè)和圖像特征提取。 一維圖像的梯度表示為函數(shù) f(x) 的導(dǎo)數(shù),而在二維圖像中,梯度是一個(gè)向量,包含兩個(gè)分量:水平方向和垂直方向的灰度變化率

    2024年02月14日
    瀏覽(25)
  • OpenCV——Scharr邊緣檢測(cè)

    OpenCV——Scharr邊緣檢測(cè)

    OpenCV——Scharr邊緣檢測(cè)由CSDN點(diǎn)云俠原創(chuàng),爬蟲(chóng)自重。如果你不是在點(diǎn)云俠的博客中看到該文章,那么此處便是不要臉的爬蟲(chóng)。 ? ?Scharr邊緣檢測(cè)算法是對(duì)Sobel算子差異性的增強(qiáng),因此兩者在檢測(cè)圖像邊緣的原理和使用方式上相同。Scharr算子的邊緣檢測(cè)濾波尺寸為3x3,因此也

    2024年01月23日
    瀏覽(13)
  • 【Opencv入門到項(xiàng)目實(shí)戰(zhàn)】(四):圖像梯度計(jì)算|Sobel算子|Scharr算子|Laplacian算子

    【Opencv入門到項(xiàng)目實(shí)戰(zhàn)】(四):圖像梯度計(jì)算|Sobel算子|Scharr算子|Laplacian算子

    在圖像處理中,梯度是指圖像中像素灰度變化的速率或幅度,我們先來(lái)看下面這張圖 假設(shè)我們想要計(jì)算出A點(diǎn)的梯度,我們可以發(fā)現(xiàn)A點(diǎn)位于邊緣點(diǎn),A點(diǎn)左邊為黑色,右邊為白色,而計(jì)算圖像的梯度可以提取出圖像中的邊緣信息,我們常用的方法是使用 Sobel算子 或 Scharr算子

    2024年02月13日
    瀏覽(17)
  • 《opencv實(shí)用探索·十二》opencv之laplacian(拉普拉斯)邊緣檢測(cè),Scharr邊緣檢測(cè),Log邊緣檢測(cè)

    《opencv實(shí)用探索·十二》opencv之laplacian(拉普拉斯)邊緣檢測(cè),Scharr邊緣檢測(cè),Log邊緣檢測(cè)

    1、Laplacian算子 Laplacian(拉普拉斯)算子是一種二階導(dǎo)數(shù)算子,其具有旋轉(zhuǎn)不變性,可以滿足不同方向的圖像邊緣銳化(邊緣檢測(cè))的要求。同時(shí),在圖像邊緣處理中,二階微分的邊緣定位能力更強(qiáng),銳化效果更好,因此在進(jìn)行圖像邊緣處理時(shí),直接采用二階微分算子而不使

    2024年04月10日
    瀏覽(24)
  • 【OpenCv ? c++】基礎(chǔ)邊緣檢測(cè)算子 —— Laplace

    【OpenCv ? c++】基礎(chǔ)邊緣檢測(cè)算子 —— Laplace

    ?? 個(gè)人簡(jiǎn)介:CSDN「 博客新星 」TOP 10 , C/C++ 領(lǐng)域新星創(chuàng)作者 ?? 作 ?? 者: 錫蘭_CC ?? ?? 專 ?? 欄: 【OpenCV ? c++】計(jì)算機(jī)視覺(jué) ?? 若有幫助,還請(qǐng) 關(guān)注?點(diǎn)贊?收藏 ,不行的話我再努努力?????? ???????邊緣檢測(cè)是圖像處理與計(jì)算機(jī)視覺(jué)中最重要的技術(shù)之一,

    2024年02月05日
    瀏覽(59)
  • openCV實(shí)戰(zhàn)-系列教程4:圖像梯度計(jì)算(Sobel算子/開(kāi)運(yùn)算/梯度計(jì)算方法/scharr算子/lapkacian算子)、源碼解讀
?????OpenCV實(shí)戰(zhàn)系列總目錄

    openCV實(shí)戰(zhàn)-系列教程4:圖像梯度計(jì)算(Sobel算子/開(kāi)運(yùn)算/梯度計(jì)算方法/scharr算子/lapkacian算子)、源碼解讀 ?????OpenCV實(shí)戰(zhàn)系列總目錄

    打印一個(gè)圖片單獨(dú)做出一個(gè)函數(shù): 先讀進(jìn)來(lái)一個(gè)原型白色圖 打印結(jié)果: 如圖有兩個(gè)3*3的卷積核,其中A是原始圖片中的一個(gè)3*3的區(qū)域,這個(gè)A和3*3的卷積核所謂對(duì)應(yīng)位置相乘的結(jié)果就分別是左右梯度和上下梯度 假如A是這個(gè)矩陣: ?那么Gx的計(jì)算結(jié)果就為:-x1+x3-2x4+2x6-x7+x9 代碼實(shí)

    2024年02月10日
    瀏覽(23)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包