生活随笔
收集整理的這篇文章主要介紹了
【opencv】26.图像水平边缘和竖直边缘的算子数学分析
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
這里我們要細分了,雖然GxG_xGx?是對x求偏導得到,但是它反映的是在x方向上的三個像素值差異很大,那么假設黑色圖像中一條白色豎線(有10行1列),那么卷積后:
- 在白色豎線以外左邊相鄰的那一列,他的GxG_xGx?值都很大,最大為255(超過255的被賦值為255);
- 在白色豎線的每一點,他的GxG_xGx?值都為0;
- 在白色豎線以外右邊相鄰的那一列,他的GxG_xGx?值都為很大負數,會被賦值為0.
即,通過計算GxG_xGx?,可以知道這三列形成了一條白色豎線。所以GxG_xGx?是用來檢測豎直邊緣的。
同理,GyG_yGy?是對y求偏導,它反映的是在y方向上的三個像素值差異很大,但是它是用來檢測水平邊緣的。
#include <math.h>#include <iostream>
#include <string>
#include <vector>#include "opencv2/highgui/highgui.hpp"
#include "opencv2/opencv.hpp"
int main() {cv
::Mat src
= cv
::Mat
::zeros(500, 500, CV_8UC1
);cv
::Mat dst
= cv
::Mat
::zeros(500, 500, CV_8UC1
);for (int y
= 0; y
< src
.rows
; ++y
) {src
.at
<unsigned char>(y
, 250) = 255;}for (int x
= 0; x
< src
.cols
; ++x
) {src
.at
<unsigned char>(250, x
) = 255;}cv
::imshow("Image of src", src
);cv
::Mat kernel_x
= (cv
::Mat_
<char>(3, 3) << -1, 0, 1, -2, 0, 2, -1, 0, 1);cv
::Mat kernel_y
= (cv
::Mat_
<char>(3, 3) << -1, -2, -1, 0, 0, 0, 1, 2, 1);cv
::Mat dst_x
, dst_y
;cv
::filter2D(src
, dst_x
, CV_8UC3
, kernel_x
);cv
::filter2D(src
, dst_y
, CV_8UC3
, kernel_y
);cv
::imshow("Image of sobel x", dst_x
);cv
::imshow("Image of sobel y", dst_y
);cv
::imshow("Image of sobel x+y", dst_x
+ dst_y
);for (int i
= 0; i
< dst_x
.cols
; ++i
) {for (int j
= 0; j
< dst_x
.rows
; ++j
) {dst
.at
<uchar
>(j
, i
) = std
::sqrt(std
::pow(dst_x
.at
<uchar
>(j
, i
), 2) +std
::pow(dst_y
.at
<uchar
>(j
, i
), 2));}}cv
::imshow("Image of sobel 梯度", dst
);while (cv
::waitKey(0) != 'q') {};return 0;
}
原始圖:
通過GxG_xGx?計算得到:
通過GyG_yGy?計算得到:
通過Gx+GyG_x+G_yGx?+Gy?計算得到:
通過Gx2+Gy2{G_x}^2+{G_y}^2Gx?2+Gy?2計算梯度得到:
#include <iostream>
#include <string>
#include <vector>#include "opencv2/highgui/highgui.hpp"
#include "opencv2/opencv.hpp"
int main() {cv
::Mat src
= cv
::imread("pppp.png");cv
::cvtColor(src
, src
, cv
::COLOR_BGR2GRAY
);cv
::Mat dst
= src
.clone();cv
::imshow("Image of src", src
);cv
::Mat kernel_x
= (cv
::Mat_
<char>(3, 3) << -1, 0, 1, -2, 0, 2, -1, 0, 1);cv
::Mat kernel_y
= (cv
::Mat_
<char>(3, 3) << -1, -2, -1, 0, 0, 0, 1, 2, 1);cv
::Mat dst_x
, dst_y
;cv
::filter2D(src
, dst_x
, CV_8UC3
, kernel_x
);cv
::filter2D(src
, dst_y
, CV_8UC3
, kernel_y
);cv
::imshow("Image of sobel x", dst_x
);cv
::imshow("Image of sobel y", dst_y
);cv
::imshow("Image of sobel x+y", dst_x
+ dst_y
);for (int i
= 0; i
< dst_x
.cols
; ++i
) {for (int j
= 0; j
< dst_x
.rows
; ++j
) {dst
.at
<uchar
>(j
, i
) = std
::sqrt(std
::pow(dst_x
.at
<uchar
>(j
, i
), 2) +std
::pow(dst_y
.at
<uchar
>(j
, i
), 2));}}cv
::imshow("Image of sobel 梯度", dst
);while (cv
::waitKey(0) != 'q') {};return 0;
}
origin:
sobel?xsobel-xsobel?x:
sobel?ysobel-ysobel?y:
sobel x+yx+yx+y :
通過Gx2+Gy2{G_x}^2+{G_y}^2Gx?2+Gy?2計算梯度得到:
總結
以上是生活随笔為你收集整理的【opencv】26.图像水平边缘和竖直边缘的算子数学分析的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。