使用opencv优化图片(画面变清晰)

文章目录

需求

对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等

影响照片清晰度的因素

影响照片清晰度的因素有很多,主要可以从以下几个方面来分析
1. 拍摄设备

  • 相机传感器:相机传感器的大小和像素密度直接影响到图像的分辨率和细节捕捉能力。较大的传感器通常能够捕获更多的光线信息,从而产生更清晰的图像。
  • 镜头质量:镜头是决定照片清晰度的关键因素之一。镜头的光学设计、制造质量和光圈大小都会影响图像的清晰度。优质的镜头可以减少色差和像差,提高图像质量。
  • 相机稳定性:拍摄时的相机抖动会导致模糊。使用三脚架或其他稳定设备可以提高清晰度

2. 拍摄条件

  • 光线:充足的光线有助于提高图像质量。自然光或人工光源的选择与布置非常重要,过暗或过亮的光线都会影响清晰度。
  • 对焦:正确的对焦是照片清晰的基础。手动或自动对焦的选择以及对焦点的位置都需要准确。
  • 曝光:正确的曝光设置可以保证图像不过曝或欠曝,从而保持细节。

3. 拍摄参数

  • ISO感光度:高ISO值会导致更多的数字噪声,影响清晰度。在光线充足的情况下尽可能使用低ISO值。
  • 快门速度:较快的快门速度有助于冻结动作,减少运动模糊。
  • 光圈:光圈大小不仅影响景深还影响进光量,大光圈(小f值)可以带来更浅的景深,而小光圈则可以获得更大的景深范围。

4. 后期处理

  • 降噪:使用后期软件去除图像中的噪声可以提高清晰度。
  • 锐化:适度的锐化可以增强图像的边缘,使其看起来更清晰。
  • 对比度和色彩调整:适当的对比度和色彩调整可以让图像的细节更加突出。

5. 存储和传输

  • 文件格式:不同的文件格式(如JPEG、PNG、TIFF)有不同的压缩率和信息保留程度,选择合适的格式可以保证图像质量。
  • 分辨率:高分辨率的图像包含更多的细节信息,但文件体积也更大。
  • 压缩算法:压缩算法的选择和压缩等级也会影响最终的清晰度。

6. 观看介质

显示器质量:显示设备的分辨率、色彩还原能力等也会影响观看体验。显示器的亮度、对比度和分辨率同样影响图像清晰度。

其他知识

一寸照是一种标准的证件照片尺寸,在不同的国家和地区有不同的具体尺寸要求。在中国,一寸照片的常见规格如下

  • 尺寸:25mm × 35mm(宽×高)
  • 分辨率:如果用于打印,通常推荐的分辨率为300dpi(每英寸点数)

数码照片的像素尺寸

  • 小一寸:一般为220px(像素)× 330px(像素)
  • 大一寸:有时也会使用33mm × 48mm,对应的像素尺寸约为480px × 660px(300dpi)

实现

使用 OpenCV 让图像变得更加清晰,可以通过多种图像处理技术来实现。这些技术主要包括降噪、锐化、对比度增强等。

降噪

  • 噪声是图像处理中不可避免的问题,它会影响图像的质量和识别效果
  • 在进行任何锐化操作之前,通常需要先进行降噪处理,因为噪声会放大任何后续的处理操作带来的负面影响
  • 常见的噪声类型包括高斯噪声、椒盐噪声、泊松噪声等。这些噪声会对图像造成模糊、失真、对比度降低等不良影响
  • 降噪算法通常基于图像的空间域或频域特性,通过平滑处理或边缘保留技术来减少噪声

中值滤波(Median Filter)

原理:中值滤波是一种非线性滤波器,它通过对图像中的像素值进行排序并取中间值来进行滤波处理。对于图像中的每个像素,选取其周围一定区域内的所有像素值,并对其进行排序,然后将排序后的像素值的中位数赋予该像素。

特点:中值滤波能够有效去除椒盐噪声和脉冲噪声,对图像中的孤立噪声点具有较强的抑制能力。同时,它能够较好地保留图像的边缘和细节信息,不会造成图像模糊。然而,中值滤波对于高斯噪声的去除效果不佳,且计算量相对较大

高斯滤波(Gaussian Filter)

原理:高斯滤波是一种线性平滑滤波器,它利用高斯函数对图像进行加权平均,从而有效地去除噪声并平滑图像。高斯滤波通过卷积操作实现,卷积核的大小和标准差决定了滤波的强度和效果

特点:高斯滤波具有良好的平滑效果,能够有效地抑制图像中的噪声。同时,高斯滤波具有旋转不变性和尺度不变性,适用于各种方向和尺度的噪声。然而,高斯滤波会造成图像细节丢失,降低图像锐度,对椒盐噪声等非平滑噪声的去除效果不佳。
双边滤波(Bilateral Filter)

原理:双边滤波是一种边缘保留滤波方法,它不仅考虑像素的空间距离,还考虑像素值的相似性。在滤波过程中,距离中心点越近且像素值越相似的像素,其权重越大。这样,双边滤波可以有效地保留图像边缘,同时抑制噪声。

特点:双边滤波结合了图像的空间邻近度和像素值相似度,通过对像素的空间距离和颜色相似度进行加权平均来实现滤波。它常用于图像去噪、边缘增强、细节保留等。双边滤波能够较好地保留图像的边缘信息,但计算量相对较大。

测试代码

# 复制代码
import cv2  
import numpy as np
# 黑白
def denoise_image(image_path, output_path):
    img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
    dst = cv2.fastNlMeansDenoising(img, None, 10, 7, 21)
    #cv2.imwrite(output_path, dst)
    cv2.imshow('Original', img)
    cv2.imshow('dst', dst)
    cv2.waitKey(0)  
    cv2.destroyAllWindows()
#彩色
def denoise_color_image(image_path, output_path):
    img = cv2.imread(image_path)
    dst = cv2.fastNlMeansDenoisingColored(img, None, 10, 10, 7, 21)
    #cv2.imwrite(output_path, dst)
    cv2.imshow('Original', img)
    cv2.imshow('dst', dst)
    cv2.waitKey(0)  
    cv2.destroyAllWindows()

#denoise_image("test01.jpg", "test02.jpg")
denoise_color_image("test01.jpg", "test02.jpg")

双边滤波

# 复制代码
def bilateral_filtering(image_path, output_path):
     img = cv2.imread(image_path)
     dst = cv2.bilateralFilter(img, 9, 75, 75)
     cv2.imwrite(output_path, dst)

中值滤波可以有效去除椒盐噪声,但对于高斯噪声效果有限

# 复制代码
def median_filtering(image_path, output_path):
    img = cv2.imread(image_path)
    dst = cv2.medianBlur(img, 5)
    cv2.imwrite(output_path, dst)

锐化

  • 锐化可以增强图像的边缘和细节,使图像看起来更清晰。
  • 锐化可以分为两种基本类型:空间域锐化和频率域锐化

空间锐化

空间域锐化主要通过卷积操作实现

比如

Laplacian 锐化是一种基于二阶导数的锐化方法,它利用 Laplacian 算子来增强图像的边缘

import cv2
import numpy as np
import matplotlib.pyplot as plt

def laplacian_sharpen(image_path):
    img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
    laplacian = cv2.Laplacian(img, cv2.CV_64F)
    sharpened = cv2.convertScaleAbs(img - laplacian)
    return sharpened

sharp_laplacian = laplacian_sharpen(image_path)

Unsharp Masking

是一种经典的锐化方法,通过减去轻微模糊后的图像来增强边缘

def unsharp_mask(image, kernel_size=(5, 5), sigma=1.0, amount=1.0, threshold=0):
    blurred = cv2.GaussianBlur(image, kernel_size, sigma)
    unsharp_image = cv2.addWeighted(image, 1 + amount, blurred, -amount, 0)
    return unsharp_image

sharp_unsharp_mask = unsharp_mask(img, amount=1.5)

频率域锐化

频率域锐化则是通过对图像进行傅里叶变换后,在频域中进行处理,再逆变换回到空域

通过增强高频成分来锐化图像

# 复制代码
def high_frequency_boost(image, kernel_size=(5, 5), sigma=1.0, amount=1.0):
    blurred = cv2.GaussianBlur(image, kernel_size, sigma)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    high_pass = gray - blurred
    sharpened = cv2.addWeighted(gray, 1 + amount, high_pass, amount, 0)
    return sharpened

sharp_high_frequency = high_frequency_boost(img, amount=1.5)

对比测试

# 读取原始图像
image_path = 'path/to/your/input_image.jpg'
img = cv2.imread(image_path)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # 转换为 RGB 格式以正确显示颜色

# Laplacian 锐化
sharp_laplacian = laplacian_sharpen(image_path)

# Unsharp Masking
sharp_unsharp_mask = unsharp_mask(img, amount=1.5)

# High-Frequency Boosting
sharp_high_frequency = high_frequency_boost(img, amount=1.5)

# 展示图像
plt.figure(figsize=(12, 12))

plt.subplot(2, 2, 1)
plt.imshow(img)
plt.title('Original Image')
plt.axis('off')

plt.subplot(2, 2, 2)
plt.imshow(sharp_laplacian, cmap='gray')
plt.title('Laplacian Sharpened')
plt.axis('off')

plt.subplot(2, 2, 3)
plt.imshow(sharp_unsharp_mask)
plt.title('Unsharp Masking')
plt.axis('off')

plt.subplot(2, 2, 4)
plt.imshow(sharp_high_frequency, cmap='gray')
plt.title('High-Frequency Boosting')
plt.axis('off')

plt.tight_layout()
plt.show()

注意颜色通道问题

css 复制代码
报错
 high_pass = gray - blurred  报错 ValueError: operands could not be broadcast together with shapes (413,295) (413,295,3)

对比度增强

OpenCV 提供了多种方法来增强图像的对比度

常用算法

  • 直方图均衡化
    直方图均衡化是一种线性方法,通过改变图像的亮度分布来提高对比度
  • 自适应直方图均衡化
    是一种局部直方图均衡化方法,适用于图像中不同区域对比度不同的情况。
  • Gamma 校正
    Gamma 校正是一种非线性方法,用于调整图像的对比度和亮度
  • 对比度拉伸
    通过拉伸图像的灰度级范围来增强对比度

对比测试

# 复制代码
import cv2
import numpy as np
import matplotlib.pyplot as plt

# 定义直方图均衡化函数
def histogram_equalization(image):
    # 应用直方图均衡化
    eq = cv2.equalizeHist(image)
    return eq

# 定义自适应直方图均衡化函数
def adaptive_histogram_equalization(image):
    # 创建 CLAHE 对象
    clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
    # 应用自适应直方图均衡化
    cl = clahe.apply(image)
    return cl

# 定义 Gamma 校正函数
def gamma_correction(image, gamma=1.0):
    inv_gamma = 1.0 / gamma
    table = np.array([((i / 255.0) ** inv_gamma) * 255 for i in range(256)]).astype("uint8")
    # 应用 Gamma 校正查找表
    adjusted = cv2.LUT(image, table)
    return adjusted

# 定义对比度拉伸函数
def contrast_stretching(image, low_percentile=2, high_percentile=98):
    # 计算灰度级的百分位数
    low_val = np.percentile(image, low_percentile)
    high_val = np.percentile(image, high_percentile)
    
    # 应用对比度拉伸
    stretched = np.clip((image - low_val) * 255 / (high_val - low_val), 0, 255).astype(np.uint8)
    return stretched

# 读取原始图像
image_path = 'test02.jpg'
img_gray = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)

# 对灰度图像进行处理
enhanced_eq = histogram_equalization(img_gray)
enhanced_clahe = adaptive_histogram_equalization(img_gray)
enhanced_gamma = gamma_correction(img_gray, gamma=0.8)
enhanced_stretched = contrast_stretching(img_gray)

# 将处理后的灰度图像转换为彩色图像
enhanced_eq_color = cv2.cvtColor(enhanced_eq, cv2.COLOR_GRAY2RGB)
enhanced_clahe_color = cv2.cvtColor(enhanced_clahe, cv2.COLOR_GRAY2RGB)
enhanced_gamma_color = cv2.cvtColor(enhanced_gamma, cv2.COLOR_GRAY2RGB)
enhanced_stretched_color = cv2.cvtColor(enhanced_stretched, cv2.COLOR_GRAY2RGB)

# 展示图像
plt.figure(figsize=(12, 12))

plt.subplot(3, 2, 1)
plt.imshow(cv2.cvtColor(img_gray, cv2.COLOR_GRAY2RGB))
plt.title('Original Grayscale Image')
plt.axis('off')

plt.subplot(3, 2, 2)
plt.imshow(enhanced_eq_color)
plt.title('Histogram Equalization')
plt.axis('off')

plt.subplot(3, 2, 3)
plt.imshow(enhanced_clahe_color)
plt.title('Adaptive Histogram Equalization')
plt.axis('off')

plt.subplot(3, 2, 4)
plt.imshow(enhanced_gamma_color)
plt.title('Gamma Correction')
plt.axis('off')

plt.subplot(3, 2, 5)
plt.imshow(enhanced_stretched_color)
plt.title('Contrast Stretching')
plt.axis('off')

plt.tight_layout()
plt.show()
相关推荐
亿牛云爬虫专家10 分钟前
如何通过subprocess在数据采集中执行外部命令 —以微博为例
爬虫·python·数据采集·多线程·代理ip·subprocess·微博
敲代码不忘补水26 分钟前
Python Pickle 与 JSON 序列化详解:存储、反序列化与对比
开发语言·python·json
杨~friendship2 小时前
Ubuntu上使用qt和opencv显示图像
linux·开发语言·c++·qt·opencv·ubuntu
西农小陈2 小时前
python-字符排列问题
数据结构·python·算法
测试19982 小时前
使用Selenium进行网页自动化
自动化测试·软件测试·python·selenium·测试工具·自动化·测试用例
小黄酥2 小时前
Python学习笔记--模块
笔记·python·学习
UvwxyZ6662 小时前
python日志记录与命令行交互
开发语言·python
TechQuester2 小时前
OpenAI 刚刚推出 o1 大模型!!突破LLM极限
人工智能·python·gpt·算法·chatgpt
西农小陈2 小时前
python-简单的数据结构
数据结构·python·算法
无敌开心2 小时前
Django-Celery-Flower实现异步和定时爬虫及其监控邮件告警
爬虫·python·django