机器视觉初步5-2:图像增强专题

图像增强是一种提高图像质量和信息量的技术,常用于图像处理、计算机视觉和机器学习中。常见的图像增强方法包括直方图均衡化、高斯滤波、锐化、对比度拉伸、图像平滑、图像锐化、图像滤波、图像金字塔等。


以下是一些常见的图像增强方法的示例代码,使用Halcon和Python实现。

1. 直方图均衡化

图像的灰度直方图就描述了图像中灰度分布情况, 能够很直观的展示出图像中各个灰度级1所占的多少。图像的灰度直方图是灰度级的函数, 描述的是图像中具有该灰度级的像素的个数: 其中, 横坐标是灰度级, 纵坐标是该灰度级出现的率。
直方图的性质:
① 直方图反映了图像中的灰度分布规律。 它描述每个灰度级具有的像素个数, 但不包含这些像素在图像中的位置信息。 图像直方图不关心像素所处的空间位置, 因此不受图像旋转和平移变化的影响, 可以作为图像的特征。

② 任何一幅特定的图像都有唯一的直方图与之对应, 但不同的图像可以有相同的直方图。

③如果一幅图像有两个不相连的区域组成, 并且每个区域的直方图已知, 则整幅图像的直方图是该两个区域的直方图之和。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Halcon代码:

* 使用全局直方图均衡化
gen_histogram_equalizer (HistogramEqualizer, 'image', 0, 255, 70)
* 使用局部直方图均衡化
gen_histogram_equalizer (HistogramEqualizer2, 'image', 0, 255, 70)
* 全局和局部直方图均衡化的区别在于映射函数的不同,全局映射函数将图像所有像素映射到整个像素空间,而局部映射函数将图像的每个子区域映射到像素空间。

Python代码

import cv2
import numpy as np

def histogram_equalizer(image):
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    channels = cv2.split(gray)
    for channel in channels:
        hist = cv2.calcHist([channel], [0, 1], None, [256], [0, 256])
        cv2.normalize(hist, hist, 0, 255, cv2.NORM_MINMAX, -1)
    gray = cv2.merge(channels)
    return cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR)

image = cv2.imread('image.jpg')
equalized_image = histogram_equalizer(image)
cv2.imshow('Equalized image', equalized_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

图像均衡化DEMO

import cv2
import numpy as np

def gray_to_intensity(image):
    h, w, c = image.shape
    intensity = np.zeros((h, w, c))
    for row in range(h):
        for col in range(w):
            intensity[row, col, 0] = image[row, col, 0]
            intensity[row, col, 1] = image[row, col, 1]
            intensity[row, col, 2] = image[row, col, 2]
    return intensity

def reverse_intensity(intensity):
    reversed_intensity = np.zeros((h, w, c))
    for row in range(h):
        for col in range(w):
            reversed_intensity[row, col, 0] = intensity[row, col, 2]
            reversed_intensity[row, col, 1] = intensity[row, col, 1]
            reversed_intensity[row, col, 2] = intensity[row, col, 0]
    return reversed_intensity

def apply_image(image, method):
    h, w, c = image.shape
    reversed_image = method(gray_to_intensity(image))
    reversed_image = reverse_intensity(reversed_image)
    return reversed_image

def image_enhance(image):
    h, w, c = image.shape
    reversed_image = apply_image(image, np.zeros((h, w, c)))
    return reversed_image

if __name__ == '__main__':
    image = cv2.imread('lena.jpg', cv2.IMREAD_GRAYSCALE)
    image = image_enhance(image)
    cv2.imshow('image', image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

2.锐化

锐化是图像处理中的一个重要概念,用于增强图像中的细节,提高图像的清晰度和对比度。它通过在图像中增加边缘和细节,使得图像看起来更加清晰、细腻。锐化的基本原理是通过增加图像中的高频成分来增加图像的对比度和细节。
在数字图像中,我们可以将图像表示为一个二维矩阵,其中每个像素的颜色值表示图像中该位置的颜色。
矩阵中的值分为三类:低频成分、中频成分和高频成分。低频成分是图像中最常见的颜色,中频成分则是低频成分与高频成分的混合,高频成分是图像中细节和边缘的颜色。
锐化的基本思想是通过增强图像中的高频成分,即增加边缘和细节,使得图像看起来更加清晰和细腻。
具体来说,锐化的方法有很多,例如拉普拉斯算子、Roberts算子、Sobel算子等。这些方法都是通过在图像中增加边缘和细节来实现锐化的目的。
需要注意的是,过度的锐化会导致图像失真和过多的噪声,因此在实际应用中需要根据具体情况选择合适的锐化方法和参数。

2.1 拉普拉斯算子

拉普拉斯算子是一种基于二阶导数的边缘检测方法。在图像中,拉普拉斯算子可以检测具有尖锐边缘的对象,因为它在边缘处产生较大的值。
原理:拉普拉斯算子使用高斯滤波器平滑图像,然后计算图像的二阶导数。二阶导数在边缘处为零,因为图像在边缘处的斜率最大。因此,我们可以通过对二阶导数取绝对值来检测边缘2

在Halcon中,可以使用Laplacian_Sobel()函数进行拉普拉斯算子边缘检测。以下是一个示例:

* 加载图像
read_image (Image, 'input_image.jpg')
* 应用高斯滤波器
filter_image (Image, ImageFiltered, 3, 3)
* 计算拉普拉斯算子
gen_contour_sobel_xld (Laplacian, ImageFiltered, -1, 1, 0, 1)
* 寻找并标记边缘
find_edges (Laplacian, Contours, 'lines', 'true', 'true')
* 显示结果
dev_display (Image)
dev_display (Laplacian)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()

用python表示为

import cv2
import numpy as np

# 读取图像
image = cv2.imread('image.jpg', 0)

# 计算拉普拉斯算子
lap = cv2.Laplacian(image, cv2.CV_64F, ksize=5)

# 显示原始图像和拉普拉斯算子
cv2.imshow('Original Image', image)
cv2.imshow('Laplacian Image', lap)

# 显示所有窗口
cv2.waitKey(0)
cv2.destroyAllWindows()

2.2 Robert算子

Roberts算子是一种基于一阶导数的边缘检测方法。它在图像中选择垂直和水平方向上的局部最大值,从而找到边缘。
原理:Roberts算子在水平和垂直方向上分别执行梯度计算。梯度的方向角分别是-45度和45度。梯度的大小可以通过计算梯度的模来确定。3

在Halcon中,可以使用Roberts_Sobel()函数进行Roberts算子边缘检测。以下是一个示例:

* 加载图像
read_image (Image, 'input_image.jpg')
* 应用高斯滤波器
filter_image (Image, ImageFiltered, 3, 3)
* 计算Roberts算子
gen_cross_contour_xld (Cross, -1, 1, 2, 1)
gen_contour_sobel_xld (SobelX, ImageFiltered, -1, 1, 0, 1)
gen_contour_sobel_xld (SobelY, ImageFiltered, -1, 1, 0, 1)
gen_contour_sobel_xld (SobelX2, ImageFiltered, -1, 1, 0, 1)
gen_contour_sobel_xld (SobelY2, ImageFiltered, -1, 1, 0, 1)
* 绘制梯度
draw_contour_xld (Cross, -1, 1, 'black', 'true')
draw_contour_xld (SobelX, -1, 1, 'black', 'true')
draw_contour_xld (SobelY, -1, 1, 'black', 'true')
draw_contour_xld (SobelX2, -1, 1, 'black', 'true')
draw_contour_xld (SobelY2, -1, 1, 'black', 'true')
dev_display (Image)
dev_display (Cross)
dev_display (SobelX)
dev_display (SobelY)
dev_display (SobelX2)
dev_display (SobelY2)

python实现

import cv2
import numpy as np

def rotated_sobel_operator(img):
    # 将图像从RGB格式转换为灰度格式
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # 将图像进行仿射变换
    # 参数解释:[x,y,z] -- 旋转中心,旋转角度,旋转轴
    # [w,h] -- 旋转后图像的宽度,高度
    # [cx,cy] -- 旋转中心
    # [R,G,B] -- 旋转后图像的颜色

    rotated_img = cv2.getRotationMatrix2D((0, 0), 45, 0.5)
    rotated_img = cv2.warpAffine(gray, rotated_img, (img.shape[1], img.shape[0]))

    # 使用Roberts算子进行边缘检测
    threshold_value = 50
    threshold_count = 3
    thresholded_image = cv2.threshold(rotated_img, threshold_value, 255, cv2.THRESH_BINARY)

    # 将边缘图像转换回灰度图像
    edge_image = cv2.bitwise_not(thresholded_image)

    return edge_image

# 示例用法
img = cv2.imread('input.jpg', cv2.IMREAD_GRAYSCALE)
edge_image = rotated_sobel_operator(img)
cv2.imwrite('output.jpg', edge_image)

cv2.waitKey(0)
cv2.destroyAllWindows()

这个代码首先将图像转换为灰度图像,然后对图像进行仿射变换。接下来,它使用Roberts算子进行边缘检测,并将结果保存为新的图像。

2.3 Sobel算子

Sobel算子是一种基于一阶导数的边缘检测方法。它在图像中选择水平和垂直方向上的局部最大值,从而找到边缘。
原理:Sobel算子在水平和垂直方向上分别执行梯度计算。梯度的方向角分别是-45度和45度。梯度的大小可以通过计算梯度的模来确定。
在Halcon中,可以使用Sobel_Sobel()函数进行Sobel算子边缘检测。以下是一个示例:

* 加载图像
read_image (Image, 'input_image.jpg')
* 应用高斯滤波器
filter_image (Image, ImageFiltered, 3, 3)
* 计算Sobel算子
gen_cross_contour_xld (Cross, -1, 1, 2, 1)
gen_contour_sobel_xld (SobelX, ImageFiltered, -1, 1, 0, 1)
gen_contour_sobel_xld (SobelY, ImageFiltered, -1, 1, 0, 1)
gen_contour_sobel_xld (SobelX2, ImageFiltered, -1, 1, 0, 1)
gen_contour_sobel_xld (SobelY2, ImageFiltered, -1, 1, 0, 1)
* 绘制梯度
draw_contour_xld (Cross, -1, 1, 'black', 'true')
draw_contour_xld (SobelX, -1, 1, 'black', 'true')
draw_contour_xld (SobelY, -1, 1, 'black', 'true')
draw_contour_xld (SobelX2, -1, 1, 'black', 'true')
draw_contour_xld (SobelY2, -1, 1, 'black', 'true')
dev_display (Image)
dev_display (Cross)
dev_display (SobelX)
dev_display (SobelY)
dev_display (SobelX2)
dev_display (SobelY2)

Sobel算子是一种用于边缘检测的二维离散微分算子,它将图像中每个像素的灰度值与其相邻的8个像素的灰度值相加,然后将结果乘以一个系数后求和。接下来,将该和与该像素的原始灰度值进行比较,并将其绝对值的大小作为该像素的梯度值。
以下是一个使用Python实现Sobel算子的示例:

import cv2
import numpy as np

def sobel_filter(image, xorder, yorder):
    dst = cv2.Sobel(image, cv2.CV_64F, xorder, yorder, ksize=1, scale=1, delta=0)
    dst = cv2.convertScaleAbs(dst)
    return dst

# 读取图像
image = cv2.imread('image.jpg')

# 设置X和Y方向的阈值
xorder = 5
yorder = 5

# 应用Sobel算子
dst = sobel_filter(image, xorder, yorder)

# 显示原图像和Sobel算子的结果
cv2.imshow('Original Image', image)
cv2.imshow('Sobel Image', dst)

# 等待按键并关闭窗口
cv2.waitKey(0)
cv2.destroyAllWindows()

在上述代码中,sobel_filter函数接受一个np.ndarray作为输入,ksize=1表示使用快速卷积滤波器,cv2.CV_64F表示使用64位浮点类型,cv2.convertScaleAbs函数将结果转换为绝对值。
请注意,Sobel算子在边缘检测方面非常有效,但也有一些缺点,例如可能会出现伪影和非最大抑制问题。因此,在实践中,通常会结合其他边缘检测方法(如Laplacian算子)来提高检测的准确性。

以上是拉普拉斯算子、Roberts算子和Sobel算子的原理和实例。这些算子在图像处理中具有广泛的应用,可以用于检测边缘、角点3和其他特征。

3.对比度拉伸

对比度拉伸是一种常用的图像处理技术,用于提高图像的视觉效果和可读性。通过对图像中的每个像素值进行处理,调整其亮度和暗度,可以增加图像中的对比度。
在对比度拉伸过程中,通常会将暗部区域的亮度值提高,使其变得更亮,同时将亮部区域的亮度值降低,使其变得更暗。这样可以使图像中的明暗对比更加明显,提高图像的可读性。
对比度拉伸通常用于图像的预处理阶段,以减少图像噪声和提高图像质量。在某些情况下,对比度拉伸也可以用于艺术创作,通过调整图像的对比度来创造出独特的视觉效果。
需要注意的是,对比度拉伸可能会导致图像失真,因此在进行对比度拉伸时需要权衡其效果和图像质量之间的关系。

* 读取图像
read_image (Image, 'yourpics.png')

* 转为灰度图像
rgb1_to_gray (Image, GrayImage)

* 获取图像尺寸
get_image_size (GrayImage, Width, Height)

* 获取图像的宽度和高度
get_image_size (Image, Width, Height)

* 计算宽度、高度的像素值
Width_pixels := Width * 4
Height_pixels := Height * 4

* 对比度拉伸图像
scale_image(Image,ImageScaled, 0.01, 0)

* 显示拉伸后的图像
dev_display (Image)

python代码

import cv2
import numpy as np

def contrast_enhancement(image):
    h, w, _ = image.shape
    chroma_smoothing = np.ones((h, w), np.uint8)
    chroma_smoothing[:, :, 0] = (image[:, :, 1] - image[:, :, 0]) / 255.0 * 0.05
    chroma_smoothing[:, :, 1] = (image[:, :, 0] - image[:, :, 1]) / 255.0 * 0.05
    chroma_smoothing = cv2.bilateralFilter(chroma_smoothing, 15, 75, 75)
    contrast_enhancement = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    return cv2.cvtColor(chroma_smoothing, cv2.COLOR_GRAY2BGR)

image = cv2.imread('image.jpg')
enhanced_image = contrast_enhancement(image)
cv2.imshow('Enhanced image', enhanced_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

  1. 灰度级是指图像处理中的一个概念,它表示图像中每个像素的亮度值。在数字图像处理中,灰度级通常被划分为256个级别,从0(黑色)到255(白色)。在这256个级别中,0对应着黑色,255对应着白色,中间的数字对应着不同程度的灰色。灰度级的概念广泛应用于数字图像处理,包括图像压缩、图像增强、图像去噪、图像分割等。在数字图像处理中,灰度级的表示对图像的处理和分析有着重要的意义。 ↩︎

  2. 拉普拉斯算子是一个二阶微分算子,作用在空间上的每一点,用来描述该点的局部曲率。它可以用于图像处理中,比如边缘检测。它的定义为:
    拉普拉斯算子 f(x, y) = (f(x + 1, y) - f(x, y + 1)) / (2 * f’(x, y))
    在OpenCV中,拉普拉斯算子有一个同名函数 cv2.Laplacian(),可以用来计算图像的拉普拉斯算子,该函数的定义如下:
    def cv2.Laplacian(src, ddepth, kernel_size, scale=1, delta=None, returnMat=None, borderType=None)
    其中:
    • src: 输入图像,可以是CV_8U, CV_16U, CV_16S, CV_32F 或 CV_64F 类型。
    • ddepth: 输出图像的深度,必须是CV_16S, CV_32F 或 CV_64F 中的一个,默认值为 CV_32F。
    • kernel_size: 拉普拉斯算子的大小,默认值为3。
    • scale:输出图像的缩放系数,默认值为1。
    • delta: 可选参数,用来增加到输出图像中。
    • returnMat: 可选参数,如果为True,返回一个与输入图像大小和类型相同的二值图像,否则返回一个与输入图像大小相同的矩阵。
    • borderType: 像素边界类型,默认值为 BORDER_CONSTANT,表示使用常数边界。 ↩︎

  3. 角点是图像中的一种特殊像素,通常位于边缘的拐点处,即图像边界上的某个像素点。在图像中,角点是具有明显特征的像素,例如,在图像中的一维向量中,该像素点的坐标可以是极值点。角点可以使我们更容易地识别和分析图像中的形状和边界,因此,在计算机视觉和图像处理中,角点检测是一种非常重要的技术。在图像处理中,角点检测可以用于边缘检测、特征提取、姿态估计、场景重建等多种任务。常见的角点检测算法包括Harris角点检测、SIFT、SURF、FAST等。 ↩︎ ↩︎

猜你喜欢

转载自blog.csdn.net/KHASIX/article/details/131281998
5-2
今日推荐