卷积的应用
图像边缘提取
- 边缘:是像素值发生跃迁的地方,是图像的显著特征之一,在图像特的显著特征之一,在图像特诊提取、对象检测、模式识别等方面都有重要的作用。
- 捕捉/提取边缘:对图像求它的一阶导数 delta=f(x)-f(x-1),delta越大,说明像素在X方向变化越大,边缘信号越强。
Sobel算子
- 是离散微分算子,用来计算图像灰度的近似梯度
- Soble算子功能集合高斯平滑和微分求导
- 又被称为一阶微分算子,求导算子,在水平和垂直两个方向上求导,得到图像X方法于Y方法梯度图像。
- 求导的近似值,kernel=3时不是很准确,OpenCV使用改进版本Scharr函数,算子如下:
API说明
- CV::Sobel
cv::Sobel(
InputArray src,//输入图像
OutputArray dst,//输出图像,大小与输入图像一致
int depth,//输出图像深度
int dx,//X方向,几阶导数
int dy,//Y方向,几阶导数
int ksize,//SOBEL算子kernel大小,必须是 1、3、5、7
double scale=1,
double delta=0,
int borderType=BORDER_DEFAULT
)
- cv::Scharr
cv::Scharr(
InputArray Src,//输入图像
OutputArray dst,//输出图像,大小与输入图像一致
int depth,//输出图像深度
int dx,//X方向,几阶导数
int dy,//Y方向,几阶导数
double scale=1,
double delta=0,
int borderType=BORDER_DEFAULT
)
其他API
-
GaussianBlur(src,dst,Size(3,3),0,0,BORDER_DEFAULT);
-
cvtColor(src,gray,COLOR_RGB2GRAY);
-
addWeighted(A,0.5,B,0.5,0,AB);
-
convertScaleAbs(A,B)//计算图像A的像素绝对值,输出到图像B
dst(I)=saturate\_cast<ucahr>(|src(I)*alpha+beta|)
代码
实现:
#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
using namespace cv;
int main(int argc,char** argv){
Mat src,dst;
src=imread("E:/opencv/zzz/hbz.jpg");
if(!src.data){
printf("could not load image...\n");
return -1;
}
char INPUT_TITLE[]="input image";
char OUTPUT_TITLE[]="Final Result";
namedWindow(INPUT_TITLE,CV_WINDOW_AUTOSIZE);
namedWindow(OUTPUT_TITLE,CV_WINDOW_AUTOSIZE);
imshow(INPUT_TITLE,src);
GaussianBlur(src,dst,Size(3,3),0,0);
Mat gray_src;
cvtColor(dst,gray_src,CV_BGR2GRAY);
imshow("gray image",gray_src);
Mat xgrad,ygrad;
Scharr(gray_src,xgrad,CV_16S,1,0);
Scharr(gray_src,ygrad,CV_16S,0,1);
//Sobel(gray_src,xgrad,CV_16S,1,0,3);
//Sobel(gray_src,ygrad,CV_16S,0,1,3);
convertScaleAbs(xgrad,xgrad);
convertScaleAbs(ygrad,ygrad);
/*
Sobel(gray_src,xgrad,-1,1,0,3);
Sobel(gray_src,ygrad,-1,0,1,3);*/
imshow("xgrad",xgrad);
imshow("ygrad",ygrad);
/*
Mat xygrad;
addWeighted(xgrad,0.5,ygrad,0.5,0,xygrad);
imshow("Final Result",xygrad);*/
Mat xygrad=Mat(xgrad.size(),xgrad.type());
printf("type:%d",xgrad.type());
int width=xgrad.cols;
int height=ygrad.rows;
for(int row=0;row<height;row++){
for(int col=0;col<width;col++){
int xg=xgrad.at<uchar>(row,col);
int yg=ygrad.at<uchar>(row,col);
int xy=xg+yg;
xygrad.at<uchar>(row,col)=saturate_cast<uchar>(xy);
}
}
imshow(OUTPUT_TITLE,xygrad);
waitKey(0);
return 0;
}
显示
注:笔记来源观看此教程的记录:https://www.bilibili.com/video/BV1Q54y1z7kz?p=18