欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-03-25 22:07:34
...

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

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

效果如下:

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

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);