【图像处理知识复习】13 Sobel一阶微分算法 C++,Matlab实现

本文介绍了一种使用3x3模板的全方向微分算子来计算图像中水平和垂直方向的梯度信息的方法。提供了Matlab和C++两种实现方式,并展示了如何通过点乘和求和来计算梯度,以及如何进行归一化处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

两个模板,分别求水平方向,和竖直方向的梯度信息。


效果如下:


1. Matlab实现:

%一种奇数(3x3)模板下的全方向微分算子。
%%
clc;clear;
f = rgb2gray(imread('D:/Code/Image/classic.jpg'));
figure('name','原图'),imshow(f);
f = double(f);
[row,col] = size(f);

%%
maskx = [-1 -2 -1;0 0 0;1 2 1];
masky = [-1 0 1;-2 0 2;-1 0 1];
g = zeros(row,col);
for i=2:row-1
    for j=2:col-1 %当前像素为i,j
        tempx = sum(sum(maskx.*f(i-1:i+1, j-1:j+1))); 
        tempy = sum(sum(masky.*f(i-1:i+1, j-1:j+1)));
        g(i,j) = round(sqrt(tempx^2+tempy^2));
    end
end

%%
figure('name','多向');
g=mat2gray(g);%将matrix值映射到[0,1]
imshow(g);

2. C++实现:

#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;

int main()
{
	Mat img = imread("D:/Code/Image/classic.jpg", 0);
	imshow("原图", img);

	Mat mask_vertical = (cv::Mat_<uchar>(3, 3) << -1, -2, -1, 0, 0, 0, 1, 2, 1);
	Mat mask_horizontal = (cv::Mat_<uchar>(3, 3) << -1, 0, 1, -2, 0, 2, -1, 0, 1);
	Mat new_img = Mat::zeros(img.size(), CV_64F);
	for (int i = 2; i < img.rows-2; i++)  // 规定当前像素为中间
	{
		for (int j = 2; j < img.cols-2; j++)
		{
			Mat block = img(Range(i - 1, i + 2), Range(j - 1, j + 2));
			double vertical = block.dot(mask_vertical);
			double horizontal = block.dot(mask_horizontal);
			new_img.at<double>(i, j) = sqrt(pow(vertical, 2) + pow(vertical, 2));
			//cout << new_img.at<double>(i, j) << endl;
		}
	}
	normalize(new_img, new_img, 255, 0, NORM_MINMAX);
	new_img.convertTo(new_img, CV_8UC1);
	imshow("效果图", new_img);
	waitKey(0);
	return 0;
}

知识点:

1)取块操作:

Mat block = img(Range(i - 1, i + 2), Range(j - 1, j + 2));

2)定义3x3模板,并赋值:

Mat mask_vertical = (cv::Mat_<uchar>(3, 3) << -1, -2, -1, 0, 0, 0, 1, 2, 1);

3) 类型问题,点乘再求和后,值会非常大,所以定义double类型,显示时先归一化到0-255,再将类型转化为uchar:

Mat new_img = Mat::zeros(img.size(), CV_64F);

normalize(new_img, new_img, 255, 0, NORM_MINMAX);
new_img.convertTo(new_img, CV_8UC1);
imshow("效果图", new_img);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.Q

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值