目录
实验原理
在OpenCV中,Scharr函数用于计算图像的一阶导数,通常用于边缘检测任务。Scharr算子与Sobel算子类似,但提供了更好的精度,尤其是在图像边缘细节较多的情况下。Scharr算子使用了3x3的核,其权重设计使得在理论上可以获得更高的准确度。
函数原型
void Scharr(InputArray src, OutputArray dst,
int ddepth, int dx, int dy, double scale=1,
double delta=0, int borderType=BORDER_DEFAULT);
参数说明
src: 输入图像,可以是单通道或多通道图像,每个通道可以是8位或32位浮点类型。
dst: 输出图像。输出图像将具有与源图像相同的大小和通道数,但深度由ddepth参数指定。
ddepth: 指定输出图像的深度。可以是CV_16S, CV_32F 或 CV_64F。
dx: 在x方向上的求导次数,通常是1(表示计算x方向的梯度)。
dy: 在y方向上的求导次数,通常是1(表示计算y方向的梯度)。
scale: 可选参数,用于缩放导数结果。默认值为1。
delta: 可选参数,用于加到导数结果上的偏移量。默认值为0。
borderType: 可选参数,指定边界扩展方式。默认值为BORDER_DEFAULT,通常意味着BORDER_REFLECT_101。
示例代码
下面是一个使用Scharr函数来计算图像梯度的C++示例:
#include <opencv2/opencv.hpp>
#include <iostream>
int main(int argc, char** argv)
{
// 读取图像文件
cv::Mat img = cv::imread("5.png", cv::IMREAD_GRAYSCALE);
if (img.empty())
{
std::cout << "Error: Image not found or unable to read the image." << std::endl;
return -1;
}
// 创建输出图像
cv::Mat grad_x, grad_y;
// 计算x方向和y方向的梯度
cv::Scharr(img, grad_x, CV_32F, 1, 0); // x方向
cv::Scharr(img, grad_y, CV_32F, 0, 1); // y方向
// 转换回8位图像
cv::convertScaleAbs(grad_x, grad_x);
cv::convertScaleAbs(grad_y, grad_y);
// 将两个方向的梯度组合成最终的边缘图像
cv::Mat abs_grad;
cv::addWeighted(grad_x, 0.5, grad_y, 0.5, 0, abs_grad);
// 显示原图和边缘检测后的图像
cv::namedWindow("Original Image", cv::WINDOW_NORMAL);
cv::imshow("Original Image", img);
cv::namedWindow("Scharr Gradient X", cv::WINDOW_NORMAL);
cv::imshow("Scharr Gradient X", grad_x);
cv::namedWindow("Scharr Gradient Y", cv::WINDOW_NORMAL);
cv::imshow("Scharr Gradient Y", grad_y);
cv::namedWindow("Combined Gradients", cv::WINDOW_NORMAL);
cv::imshow("Combined Gradients", abs_grad);
// 等待用户按键后退出
cv::waitKey(0);
return 0;
}
在这个示例中,我们读取了一张灰度图像,并使用cv::Scharr函数分别计算了x方向和y方向的梯度。然后,我们将梯度转换为8位图像以便于显示,并将两个方向的梯度合并成一个图像。最后,我们显示了原始图像和各个方向的梯度图像。