图像处理实验:边缘,锐化

半邻域平均

设计思路

半邻域平均法通过分析像素邻域内的灰度差异来判断是否存在边缘。如果邻域内没有显著的边缘,使用邻域平均值进行平滑;如果有边缘,则根据邻域内的细节信息来调整像素值,以保留边缘细节。

实现方法

对每个像素点,将邻域分为两组,比较它们的平均灰度值。如果两组之间的差异小于预设阈值,就用全邻域的平均值替换当前像素值;否则,根据具体情况选择合适的组平均值进行替换,以保护边缘信息。

matlab代码

matlab 复制代码
% 读入图像
img = imread('G.png');
% 转换为灰度图
gray_img = rgb2gray(img);
% 给图像添加噪声
noisy_img = imnoise(gray_img, "salt & pepper", 0.02);
% 设置阈值
T = 5;
% 应用自定义的半领域平均滤波器
filtered_img = half_domain_average_filter(noisy_img, T);
% 应用平均滤波器
filtered_img1 = mean_filter_3x3(noisy_img);
% 将原图,噪声图和滤波后的图显示在一个窗口中
subplot(2, 2, 1);
imshow(gray_img);
title('原图');
subplot(2, 2, 2);
imshow(noisy_img);
title('噪声图');
subplot(2, 2, 3);
imshow(filtered_img);
title('半领域平均滤波器');
subplot(2, 2, 4);
imshow(filtered_img1);
title('平均滤波器')
function output_img = half_domain_average_filter(input_img, T)
    % 将输入图像转换为双精度以进行计算
    input_img = double(input_img);
    % 获取图像的尺寸
    [rows, cols] = size(input_img);
    % 准备输出图像
    output_img = zeros(rows, cols);
    % 遍历图像的每个像素
    for i = 1:rows
        for j = 1:cols
            neighborhood = zeros(1, 8);
            index = 1;
            % 将8个领域保存到数组中
            for x = -1:1
                for y = -1:1
                    if i + x >= 1 && i + x <= rows && j + y >= 1 && j + y <= cols
                        neighborhood(index) = input_img(i + x, j + y);
                        index = index + 1;
                    end
                end
            end
            % 给领域排序
            neighborhood = sort(neighborhood);
            % M3是最小的3个值的平均值,M6是最大的5个和中心点的平均值,N是全部的平均值
            sum_M3 = (neighborhood(1) + neighborhood(2) + neighborhood(3)) / 3;
            sum_M6 = (neighborhood(4) + neighborhood(5) + neighborhood(6) + neighborhood(7) + neighborhood(8) + input_img(i, j)) / 6;
            sum_N = sum(neighborhood) / 8;
            % 如果M3和M6的差值小于T,说明没有边界,使用N作为输出,否则输出M6
            if abs(sum_M3 - sum_M6) < T
            output_img(i, j) = sum_N;
            else
            output_img(i, j) = sum_M6;
            end
        end
    % 将输出图像转换回原始的数据类型
    output_img = uint8(output_img);
    end
end

效果

百分比滤波器

设计思路

百分比滤波器利用邻域内像素值的统计分布来决定目标像素的新值,选择一个特定的百分位数(如中位数代表50%的百分比)作为输出值。这种方法旨在在去除噪声的同时,尽量保持图像的原始细节和清晰度,比传统的平均滤波器在保持边缘信息方面表现得更好。

实现方法

对图像中的每个像素,定义一个包含该像素及其周围像素的窗口。然后,将这个窗口内所有像素的灰度值进行排序,根据预设的百分比选取相应的灰度值作为该像素的新值。例如,如果设置为50%,则选取中值;如果设置为25%,则选取下四分位数。这种方法的关键在于合理选择百分比,以适应不同的噪声条件和图像细节保留需求。

matlab代码

matlab 复制代码
% 读取输入图像,转换为灰度图像,然后应用百分位滤波器
img = imread('G.png');
grayImg = rgb2gray(img);
percentile = 50;
% 添加椒盐噪声
noisyImg = imnoise(grayImg, 'salt & pepper', 0.02);
% 应用百分位滤波器
outputImg = percentile_Filter(noisyImg, percentile);
% 应用平均滤波器
avgOutputImg = mean_filter_3x3(noisyImg);
% 显示灰度图像,添加噪声后的图像,平均滤波器输出和百分位滤波器输出
figure;
subplot(2, 2, 1);
imshow(grayImg);
title('原图像');
subplot(2, 2, 2);
imshow(noisyImg);
title('添加椒盐噪声后的图像');
subplot(2, 2, 3);
imshow(avgOutputImg);
title('平均滤波器输出');
subplot(2, 2, 4);
imshow(outputImg);
title('百分位滤波器输出, percentile = 50');
function outputImage = percentile_Filter(inputImage, percentile)
    % 确保输入图像是灰度的
    if size(inputImage, 3) == 3
        inputImage = rgb2gray(inputImage);
    end
    % 将图像转换为double类型以进行计算
    inputImage = double(inputImage);
    % 获取输入图像的尺寸
    [rows, cols] = size(inputImage);
    % 初始化输出图像
    outputImage = zeros(rows, cols);
    % 计算需要选择的百分位索引
    index = round(9 * percentile / 100) + 1; % 因为3x3窗口有9个元素
    % 对每个像素应用百分比滤波器
    for i = 2:rows-1
        for j = 2:cols-1
            % 提取3x3邻域
            window = inputImage(i-1:i+1, j-1:j+1);
            % 将邻域像素值排序
            sortedValues = sort(window(:));
            % 选择对应的百分位数的像素值
            outputImage(i, j) = sortedValues(index);
        end
    end
    % 将输出图像转换回原始图像类型
    outputImage = uint8(outputImage);
end

效果

最大-最小锐化

设计思路

最大-最小锐化技术基于一种简单的原理,即对图像中的每个像素,考察其邻域内的最大值和最小值,然后根据该像素与这两个极值的距离来决定其最终值。如果像素值接近最大值,它将被设置为邻域的最大值;如果它接近最小值,则被设置为邻域的最小值。这种方法旨在增强图像的对比度,使得边缘和细节更加突出。

实现方法

  1. 遍历图像中的每个像素点。
  2. 对于每个像素点,定义一个邻域窗口,并找出该窗口内的最大值和最小值。
  3. 计算当前像素值与最大值、最小值的差距。
  4. 如果当前像素值距离最大值更近,则将该像素的新值设置为邻域内的最大值;如果距离最小值更近,则设置为最小值。

matlab代码

matlab 复制代码
% 读取输入图像,转换为灰度图像,然后应用百分位滤波器
img = imread('G.png');
grayImg = rgb2gray(img);
% 添加高斯模糊
noisyImg = imgaussfilt(grayImg, 1.5);
% 应用最大最小锐化滤波器
outputImg = MaxMinSharpeningFilter(noisyImg);
% 显示灰度图像,高斯模糊后的图像和最大最小锐化滤波器输出
figure;
subplot(1, 3, 1);
imshow(grayImg);
title('原图像');
subplot(1, 3, 2);
imshow(noisyImg);
title('添加高斯模糊后的图像');
subplot(1, 3, 3);
imshow(outputImg);
title('最大最小锐化滤波器输出');
function outputImage = MaxMinSharpeningFilter(inputImage)
    % 确保输入图像是灰度的
    if size(inputImage, 3) == 3
        inputImage = rgb2gray(inputImage);
    end
    % 将图像转换为double类型以进行计算
    inputImage = double(inputImage);
    % 获取输入图像的尺寸
    [rows, cols] = size(inputImage);
    % 初始化输出图像
    outputImage = zeros(rows, cols);
    % 对每个像素应用最大最小锐化滤波器
    for i = 2:rows-1
        for j = 2:cols-1
            % 提取3x3邻域
            window = inputImage(i-1:i+1, j-1:j+1);
            % 计算最大值和最小值
            maxValue = max(window(:));
            minValue = min(window(:));
            % 计算当前像素与最大值和最小值的距离
            distanceToMax = abs(inputImage(i, j) - maxValue);
            distanceToMin = abs(inputImage(i, j) - minValue);
            % 选择距离较近的值作为输出
            if distanceToMax <= distanceToMin
                outputImage(i, j) = maxValue;
            else
                outputImage(i, j) = minValue;
            end
        end
    end
    % 将输出图像转换回原始图像类型
    outputImage = uint8(outputImage);
end

效果

高频提升

设计思路

高频提升是一种图像锐化技术,通过增强图像的高频分量来提升图像的细节和边缘。它的基本原理是将原始图像与其高频分量(经过高通滤波处理的图像)相加。通过这种方式,不仅保留了原图的基本结构,还强化了边缘和细节,使图像看起来更清晰。参数的选择允许控制高频分量增强的程度。

实现方法

  1. 对原图进行高通滤波处理,以提取图像的高频分量。高通滤波可以通过减去低通滤波的结果从原图中得到,或直接使用高通滤波器实现。
  2. 将高通滤波后的图像(高频分量)乘以一个参数(通常大于1),以调节高频增强的强度。
  3. 将调节后的高频分量图像与原始图像相加,得到高频提升后的图像。

matlab代码

matlab 复制代码
% 读取输入图像,转换为灰度图像,然后应用百分位滤波器
img = imread('G.png');
grayImg = rgb2gray(img);
% 应用高频增强滤波器
outputImg = HighFreqEnhancement(grayImg, 1.5);
% 显示灰度图像,高斯模糊后的图像和最大最小锐化滤波器输出
figure;
subplot(1, 2, 1);
imshow(grayImg);
title('原图像');
subplot(1, 2, 2);
imshow(outputImg);
title('高频增强滤波器输出');
function outputImage = HighFreqEnhancement(inputImage, k)
    % 将图像转换为double类型以进行计算
    inputImage = double(inputImage);
    % 定义高通滤波器核
    hpFilter = 1/9*[-1 -1 -1; -1 8 -1; -1 -1 -1];
    % 使用高通滤波器提取高频成分
    highFreqComponent = imfilter(inputImage, hpFilter, 'replicate');
    % 将高频成分加回到加权的原始图像中
    outputImage = inputImage + k * highFreqComponent;
    % 将输出图像的范围限制在0到255之间
    outputImage = max(min(outputImage, 255), 0);
    % 将输出图像转换回原始图像类型
    outputImage = uint8(outputImage);
end

效果

非线性锐化

设计思路

非线性锐化通过增强图像中的边缘来提升图像的清晰度,这种方法依赖于图像梯度的计算,即图像亮度变化的速率。梯度较大的区域通常对应于图像的边缘或细节部分。非线性锐化方法将图像的梯度值与原始图像相加,通过一个阈值参数控制锐化的强度,从而在不过度增强噪声的同时强化边缘和细节。

实现方法

  1. 计算输入图像的梯度
  2. 将计算得到的梯度幅度乘以一个阈值参数(threshold),然后加到原图像上。这个阈值参数用来调节锐化的强度。
  3. 对结果图像进行裁剪,确保像素值仍然在合法的范围内(例如0-255)。
  4. 将浮点数结果转换回无符号8位整数形式,以便显示和存储。

matlab代码

matlab 复制代码
% 读取输入图像,转换为灰度图像,然后应用百分位滤波器
img = imread('G.png');
grayImg = rgb2gray(img);
% 应用非线性锐化
outputImg = nonlinear_sharpening(grayImg, 0.15);
figure;
subplot(1, 2, 1);
imshow(grayImg);
title('原图像');
subplot(1, 2, 2);
imshow(outputImg);
title('非线性锐化输出');
function sharpened_img_uint8 = nonlinear_sharpening(img, threshold)
    % 将图像转换为double类型进行计算
    img_double = double(img);
    % 使用imgradient函数直接计算梯度幅度
    [Gmag, ~] = imgradient(img_double, 'Sobel');
    % 应用阈值参数并增强图像
    sharpened_img = img_double + threshold * Gmag;
    % 裁剪结果图像,保持在0-255范围内
    sharpened_img(sharpened_img > 255) = 255;
    sharpened_img(sharpened_img < 0) = 0;
    % 转换回无符号8位整数形式
    sharpened_img_uint8 = uint8(sharpened_img);
end

效果

边缘检测:基于Kirsch算子

设计思路

Kirsch算子用于图像的边缘检测,通过对图像应用一组特定方向的模板(或掩模),以识别图像中的边缘方向。Kirsch算子包含八个模板,每个模板对应于不同的方向(0°、45°、90°、135°等),这使得它能够检测图像中沿不同方向的边缘。

实现方法

  1. 定义Kirsch算子的八个方向模板。每个模板都设计用来响应特定方向的边缘。
  2. 根据输入的方向选择相应的Kirsch模板。方向由函数参数direction指定,其值决定使用哪个模板进行卷积。
  3. 使用所选的Kirsch模板与输入图像进行卷积运算。这一步骤将强调与模板方向相对应的边缘。

matlab代码

matlab 复制代码
% 读取输入图像,转换为灰度图像,然后应用百分位滤波器
img = imread('G.png');
grayImg = rgb2gray(img);
% 应用0,45,90,135度的Kirsch边缘检测算子
edge_img_0 = kirsch_edge_detection(grayImg, 1);
edge_img_45 = kirsch_edge_detection(grayImg, 2);
edge_img_90 = kirsch_edge_detection(grayImg, 3);
edge_img_135 = kirsch_edge_detection(grayImg, 4);
% 显示灰度图像,四个方向的Kirsch边缘检测结果
figure;
subplot(2, 3, 1);
imshow(grayImg);
title('原图像');
subplot(2, 3, 2);
imshow(edge_img_0);
title('0度');
subplot(2, 3, 3);
imshow(edge_img_45);
title('45度');
subplot(2, 3, 5);
imshow(edge_img_90);
title('90度');
subplot(2, 3, 6);
imshow(edge_img_135);
title('135度');
function edge_img_uint8 = kirsch_edge_detection(img, direction)
    % 将图像转换为double类型以进行计算
    img_double = double(img);
    % 定义Kirsch算子的八个方向模板
    kirsch_masks = {
        [5 5 5; -3 0 -3; -3 -3 -3], % North
        [-3 5 5; -3 0 5; -3 -3 -3], % North-East
        [-3 -3 5; -3 0 5; -3 -3 5], % East
        [-3 -3 -3; -3 0 5; -3 5 5], % South-East
        [-3 -3 -3; -3 0 -3; 5 5 5], % South
        [5 -3 -3; 5 0 -3; 5 -3 -3], % South-West
        [5 5 -3; 5 0 -3; 5 -3 -3], % West
        [5 5 5; 5 0 -3; -3 -3 -3]  % North-West
    };
    % 选择对应方向的Kirsch模板
    selected_mask = kirsch_masks{direction};
    % 使用选定的Kirsch模板与输入图像进行卷积运算
    edge_img = imfilter(img_double, selected_mask, 'replicate');
    % 转换为无符号8位整数形式
    edge_img_uint8 = uint8(edge_img);
end

效果

拉普拉斯算子锐化

设计思路

拉普拉斯算子锐化是一种基于二阶导数的图像锐化技术,旨在增强图像中的边缘细节。拉普拉斯算子可以突出图像中的快速变化区域,如边缘,因此在与原始图像结合时,能够有效地增加图像的对比度和锐度。

实现方法

  1. 创建拉普拉斯滤波器。该滤波器能够检测图像中的边缘区域,产生一个强调边缘的图像。
  2. 将拉普拉斯滤波器应用于输入图像。这一步产生了一个包含图像边缘信息的拉普拉斯图像。
  3. 将拉普拉斯图像与原始输入图像相加。这一步增强了原图中的边缘区域,因为拉普拉斯图像强调了边缘,从而提高了图像的总体锐度。

matlab代码

matlab 复制代码
% 读取输入图像,转换为灰度图像,然后应用百分位滤波器
img = imread('G.png');
grayImg = rgb2gray(img);
% 应用拉普拉斯锐化滤波器
outputImg = laplacian_sharpening(grayImg);
% 显示灰度图像
figure;
subplot(1, 2, 1);
imshow(grayImg);
title('原图像');
subplot(1, 2, 2);
imshow(outputImg);
title('拉普拉斯锐化滤波器输出');
function sharpened_img_uint8 = laplacian_sharpening(img)
    % 将图像转换为double类型进行计算
    img_double = double(img);
    % 创建一个拉普拉斯滤波器
    laplacian_filter = [0 -1 0; -1 4 -1; 0 -1 0];
    % 应用拉普拉斯滤波器于输入图像
    laplacian_img = imfilter(img_double, laplacian_filter, 'replicate');
    % 将拉普拉斯图像与原始输入图像相加以增强边缘
    sharpened_img = img_double + laplacian_img;
    % 裁剪结果图像,保持在0-255范围内
    sharpened_img(sharpened_img > 255) = 255;
    sharpened_img(sharpened_img < 0) = 0;
    % 转换回无符号8位整数形式
    sharpened_img_uint8 = uint8(sharpened_img);
end

效果

LoG算子锐化

设计思路

LoG(Laplacian of Gaussian)算子锐化是一种结合了高斯平滑和拉普拉斯锐化的图像处理技术。首先使用高斯滤波器对图像进行平滑处理,以减少噪声的影响;然后应用拉普拉斯算子来强调图像中的边缘信息。这种方法旨在在保留图像边缘的同时减少锐化过程中可能引入的噪声。

实现方法

  1. 对输入图像进行高斯平滑处理。
  2. 创建拉普拉斯滤波器。
  3. 将拉普拉斯滤波器应用于已平滑的图像。
  4. 将拉普拉斯处理后的图像与原始图像相加,以增强图像的边缘和细节。

matlab代码

matlab 复制代码
% 读取输入图像,转换为灰度图像,然后应用百分位滤波器
img = imread('G.png');
grayImg = rgb2gray(img);
% 应用Log锐化滤波器
outputImg = log_sharpening(grayImg, 1);
% 显示灰度图像
figure;
subplot(1, 2, 1);
imshow(grayImg);
title('原图像');
subplot(1, 2, 2);
imshow(outputImg);
title('Log锐化滤波器输出');
function sharpened_img_uint8 = log_sharpening(img, sigma)
    % 将图像转换为double类型以进行计算
    img_double = double(img);
    % 步骤1: 对输入图像进行高斯平滑处理
    % MATLAB中的imgaussfilt函数可以实现高斯滤波
    smoothed_img = imgaussfilt(img_double, sigma);
    % 步骤2: 创建拉普拉斯滤波器
    laplacian_filter = [0 -1 0; -1 4 -1; 0 -1 0];
    % 步骤3: 将拉普拉斯滤波器应用于已平滑的图像
    laplacian_img = imfilter(smoothed_img, laplacian_filter, 'replicate');
    % 步骤4: 将拉普拉斯处理后的图像与原始图像相加,以增强图像的边缘和细节
    sharpened_img = img_double + laplacian_img;  %
    % 裁剪结果图像,保持在0-255范围内
    sharpened_img(sharpened_img > 255) = 255;
    sharpened_img(sharpened_img < 0) = 0;
    % 转换回无符号8位整数形式
    sharpened_img_uint8 = uint8(sharpened_img);
end

效果

相关推荐
zaizai100717 天前
WebGL编程指南 - 颜色与纹理续
图形学
zaizai100720 天前
WebGL编程指南 - 绘制和变换三角形
图形学
zaizai100721 天前
WebGL编程指南 - 入门续
图形学
闲人编程1 个月前
使用Python实现图形学的阴影贴图算法
python·算法·图形学·贴图·阴影贴图
闲人编程1 个月前
使用Python实现图形学的纹理映射算法
开发语言·python·算法·图形学·纹理映射
闲人编程1 个月前
使用Python实现图形学的环境映射算法
开发语言·python·算法·图形学·环境映射
闲人编程1 个月前
Python实现图形学曲线和曲面的Bezier曲线算法
开发语言·python·算法·图形学·曲线·曲面·bezier
CaptainHarryChen1 个月前
从 Affine Particle-In-Cell (APIC) 到 Material Point Method (MPM 物质点法)
图形学·物理仿真·mpm·仿真算法
Jozky863 个月前
图形学论文笔记
笔记·图形学
赵青青3 个月前
DirectX9(D3D9)游戏开发:高光时刻录制和共享纹理的踩坑
图形学