// ConsoleApplication3_6_23.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
Mat src,dst,gray;
int pro_type = 0;
char* windowName = "demo";
char* windowName1 = "demo_pro";
void Image_pro(int,void*);
int _tmain(int argc, _TCHAR* argv[])
{
src = imread("test.png");
if(!src.data)
return -1;
namedWindow(windowName,CV_WINDOW_AUTOSIZE);
imshow(windowName,src);
GaussianBlur(src,src,Size(3,3),0,0,BORDER_DEFAULT);
cvtColor(src,gray,CV_RGB2GRAY);
namedWindow(windowName1,CV_WINDOW_AUTOSIZE);
createTrackbar("Type : 0-sobel 1-laplace 2-canny /n",
windowName1,&pro_type,2,Image_pro);
Image_pro(0,0);
waitKey(0);
return 0;
}
void Image_pro(int,void*){
Mat grd_x,grd_y;
Mat abs_grd_x,abs_grd_y;
Mat la_dst;
switch (pro_type)
{
case 0 :
Sobel(gray,grd_x,CV_16S,1,0,3,1,0,BORDER_DEFAULT);
convertScaleAbs(grd_x,abs_grd_x);
Sobel(gray,grd_y,CV_16S,0,1,3,1,0,BORDER_DEFAULT);
convertScaleAbs(grd_y,abs_grd_y);
addWeighted(abs_grd_x,0.5,abs_grd_y,0.5,0,dst);
break;
case 1:
Laplacian(gray,la_dst,CV_16S,3,1,0,BORDER_DEFAULT);
convertScaleAbs(la_dst,dst);
break;
case 2:
Canny(gray,dst,20,50 * 3,3);
break;
default:
break;
}
imshow(windowName1,dst);
}
效果:
1、
该函数接受了以下参数:
- src_gray: 在本例中为输入图像,元素类型 CV_8U
- grad_x/grad_y: 输出图像.
- ddepth: 输出图像的深度,设定为 CV_16S 避免外溢。
- x_order: x 方向求导的阶数。
- y_order: y 方向求导的阶数。
- scale, delta 和 BORDER_DEFAULT: 使用默认值
函数接受了以下参数:
- src_gray: 输入图像。
- dst: 输出图像
- ddepth: 输出图像的深度。 因为输入图像的深度是 CV_8U ,这里我们必须定义 ddepth = CV_16S 以避免外溢。
- kernel_size: 内部调用的 Sobel算子的内核大小,此例中设置为3。
- scale, delta 和 BORDER_DEFAULT: 使用默认值。
输入参数:
- detected_edges: 原灰度图像
- detected_edges: 输出图像 (支持原地计算,可为输入图像)
- lowThreshold: 用户通过 trackbar设定的值。
- highThreshold: 设定为低阈值的3倍 (根据Canny算法的推荐)
- kernel_size: 设定为 3 (Sobel内核大小,内部使用)
sobel函数
void sobel(Mat* src,Mat* dst){
if(src->channels() != 1)
{
cout<<"please input gray_image"<<endl;
return;
}
Mat grd_x = Mat::zeros(src->size(),src->type());
Mat grd_y = Mat::zeros(src->size(),src->type());
for (int i = 1;i < src->rows-1;++i)
{
const uchar* pre = src->ptr<uchar>(i-1);
const uchar* cur = src->ptr<uchar>(i);
const uchar* nex = src->ptr<uchar>(i+1);
uchar* px = grd_x.ptr<uchar>(i);
uchar* py = grd_y.ptr<uchar>(i);
for (int j = 1;j < src->cols-1;++j)
{
/*
-1 0 1 -2 0 2 -1 0 1
*/
*px++ = saturate_cast<uchar>(-1 * pre[j-1] + 0 * pre[j] + 1 * pre[j+1]
-2 * cur[j-1] + 0 * cur[j] + 2 * cur[j+1]
-1 * nex[j-1] + 0 * nex[j] + 1 * nex[j+1]);
*py++ = saturate_cast<uchar>(-1 * pre[j-1] -2 * pre[j] -1 * pre[j+1] +
0 * cur[j-1] + 0 * cur[j] + 0 * cur[j+1] +
1 * nex[j-1] + 2 * nex[j] + 1 * nex[j+1]);
}
}
Mat abs_grdx,abs_grdy;
convertScaleAbs(grd_x,abs_grdx);
convertScaleAbs(grd_y,abs_grdy);
addWeighted(abs_grdx,0.5,abs_grdy,0.5,0,*dst);
}