本文全面讲解OpenCV图像预处理的七大核心技术(插值方法、边缘填充、图像矫正(透视变换)、图像掩膜、ROI切割、图像添加水印、图像噪点消除),每个知识点都配有详细解释和实用代码示例,帮助初学者建立系统的图像处理知识体系。


一、插值方法:图像缩放的核心技术

插值是在图像缩放或旋转时估算新像素值的方法,不同方法在速度和质量上有显著差异。

1. 最近邻插值

  • 原理:直接取最邻近像素的值
  • 特点:速度最快,但会产生锯齿
  • 适用场景:实时系统或低功耗设备
resized = cv2.resize(img, (800, 600), interpolation=cv2.INTER_NEAREST)

2. 双线性插值

  • 原理:取周围4个像素的加权平均值
  • 特点:速度与质量平衡
  • 适用场景:大多数常规缩放需求
resized = cv2.resize(img, (800, 600), interpolation=cv2.INTER_LINEAR)

3. 双三次插值

  • 原理:取周围16个像素的加权平均值
  • 特点:质量高但速度慢
  • 适用场景:高质量图像处理
resized = cv2.resize(img, (800, 600), interpolation=cv2.INTER_CUBIC)

4. Lanczos插值

  • 原理:使用sinc函数进行插值
  • 特点:最高质量,最慢速度
  • 适用场景:专业图像处理
resized = cv2.resize(img, (800, 600), interpolation=cv2.INTER_LANCZOS4)

5.完整示例

import cv2# 读图
cat = cv2.imread('../images/1.jpg')
w = cat.shape[1]
h = cat.shape[0]# 旋转
# 获取旋转矩阵
M = cv2.getRotationMatrix2D((w//2, h//2), 45, 0.5)# 应用仿射变换函数
dst = cv2.warpAffine(cat, M, (w, h))# 最近邻插值  flags=cv2.INTER_NEAREST
dst1 = cv2.warpAffine(cat, M, (w, h), flags=cv2.INTER_NEAREST)# 双线性插值  单线性插值  插两次:水平和垂直
dst2 = cv2.warpAffine(cat, M, (w, h), flags=cv2.INTER_LINEAR)# 像素区域插值  缩小:均值滤波   放大:整数  最近邻  不是整数  双线性 4点  2 x 2
dst3 = cv2.warpAffine(cat, M, (w, h), flags=cv2.INTER_AREA)# 双三次插值  16个  4 x 4  w_i   w_j
dst4 = cv2.warpAffine(cat, M, (w, h), flags=cv2.INTER_CUBIC)# Lanczos插值  64个  8 x 8
dst5 = cv2.warpAffine(cat, M, (w, h), flags=cv2.INTER_LANCZOS4)# 显示
cv2.imshow('dst', dst)
cv2.imshow('dst1', dst1)
cv2.imshow('dst2', dst2)
cv2.imshow('dst3', dst3)
cv2.imshow('dst4', dst4)
cv2.imshow('dst5', dst5)cv2.waitKey(0)
cv2.destroyAllWindows()

二、边缘填充:处理边界问题的关键

当进行卷积操作时,图像边界需要特殊处理,OpenCV提供多种填充方式。

1. 填充方法对比

方法原理效果示例
BORDER_REPLICATE复制边界像素值`aaaa
BORDER_REFLECT镜像反射边界`fedc
BORDER_REFLECT_101反射不含边界`gfed
BORDER_CONSTANT用常数填充`0000
BORDER_WRAP循环填充`cdef

2. 完整示例

import cv2# 读图
cat = cv2.imread('../images/1.jpg')
w = cat.shape[1]
h = cat.shape[0]# 旋转
# 获取旋转矩阵
M = cv2.getRotationMatrix2D((w//2, h//2), 45, 0.5)# 应用仿射变换函数
dst = cv2.warpAffine(cat, M, (w, h))# 最近邻插值   边界复制
dst1 = cv2.warpAffine(cat, M, (w, h), flags=cv2.INTER_NEAREST,borderMode=cv2.BORDER_REPLICATE)# 双线性插值    边界反射
dst2 = cv2.warpAffine(cat, M, (w, h), flags=cv2.INTER_LINEAR,borderMode=cv2.BORDER_REFLECT)# 像素区域插值   边界反射101
dst3 = cv2.warpAffine(cat, M, (w, h), flags=cv2.INTER_AREA,borderMode=cv2.BORDER_REFLECT_101)# 双三次插值  边界常数
dst4 = cv2.warpAffine(cat, M, (w, h), flags=cv2.INTER_CUBIC,borderMode=cv2.BORDER_CONSTANT,borderValue=(0,0,255))# Lanczos插值  边界包裹
dst5 = cv2.warpAffine(cat, M, (w, h), flags=cv2.INTER_LANCZOS4,borderMode=cv2.BORDER_WRAP)# 显示
cv2.imshow('dst', dst)
cv2.imshow('dst1', dst1)
cv2.imshow('dst2', dst2)
cv2.imshow('dst3', dst3)
cv2.imshow('dst4', dst4)
cv2.imshow('dst5', dst5)cv2.waitKey(0)
cv2.destroyAllWindows()

三、图像矫正:透视变换的应用

透视变换可以将倾斜视角的图像矫正为正视角,常用于文档扫描和车牌识别。

1. 透视变换四步法

  1. 识别源点:选择图像中的四个特征点
  2. 定义目标点:确定矫正后的位置
  3. 计算变换矩阵:使用getPerspectiveTransform
  4. 应用变换:使用warpPerspective

2. 完整示例

import cv2
import numpy as np# 读图
card = cv2.imread('../images/3.png')
shape = card.shape# 获取透视变换矩阵
# 原图中卡片的四个角点:左上、右上、左下、右下
# [[178, 100], [487, 134], [124, 300], [490, 350]]
pt1 =np.float32([[178, 100], [487, 134], [124, 300], [490, 350]])
pt2 =np.float32([[0,0],[shape[1],0],[0,shape[0]],[shape[1],shape[1]]])M = cv2.getPerspectiveTransform(pt1,pt2)# 透视变换
dst = cv2.warpPerspective(card,M,(shape[1],shape[0]),cv2.INTER_LINEAR,borderMode=cv2.BORDER_REFLECT)cv2.imshow('card',card)
cv2.imshow('dst',dst)cv2.waitKey(0)
cv2.destroyAllWindows()

四、图像掩膜:精确控制处理区域

掩膜是二值化图像,用于指定哪些区域需要处理或保留,以实现特定任务的目标。

掩膜操作三部曲

  1. 创建掩膜:手动绘制或通过阈值处理生成
  2. 应用掩膜:使用按位与操作保留目标区域
  3. 颜色替换:修改特定区域颜色

第一种:

# 创建圆形掩膜
mask = np.zeros(img.shape[:2], dtype=np.uint8)
cv2.circle(mask, (200, 200), 100, 255, -1)# 应用掩膜
masked_img = cv2.bitwise_and(img, img, mask=mask)# 颜色替换
img[mask == 255] = (0, 255, 0)  # 将掩膜区域变为绿色

第两种(完整):

cv2.inRange用于进行多通道图像(尤其是彩色图像)的阈值操作。

import cv2
import numpy as np# 读图
demo = cv2.imread('../images/demo.png')
demo = cv2.resize(demo,(500,500))# 颜色空间转换  转 HSV
demo_hsv = cv2.cvtColor(demo,cv2.COLOR_BGR2HSV)# 定义颜色范围
low = np.array([0,43,46])
high = np.array([10,255,255])# 创建掩膜  cv2.inRange(img,low,high)  传 hsv 颜色空间下的图像  二维
mask = cv2.inRange(demo_hsv,low,high)# 颜色提取 cv2.bitwise_and(src1,src2[,mask])   传的是原图
dst = cv2.bitwise_and(demo,demo,mask=mask)cv2.imshow('demo',demo)
cv2.imshow('mask',mask)
cv2.imshow('dst',dst)cv2.waitKey(0)
cv2.destroyAllWindows()

含颜色替换操作示例:

import cv2
import numpy as np# 读图
demo = cv2.imread('../images/demo.png')
demo = cv2.resize(demo,(500,500))# 颜色空间转换  转 HSV
demo_hsv = cv2.cvtColor(demo,cv2.COLOR_BGR2HSV)# 定义颜色范围
low = np.array([0,43,46])
high = np.array([10,255,255])# 创建掩膜  cv2.inRange(img,low,high)  传 hsv 颜色空间下的图像  二维
mask = cv2.inRange(demo_hsv,low,high)# 颜色替换  布尔索引
arr = (mask == 255)
# print(arr)demo[arr] = (0, 255, 0)
# demo[mask == 255] = (0, 255, 0)cv2.imshow('demo',demo)cv2.waitKey(0)
cv2.destroyAllWindows()

五、ROI切割:聚焦关键区域

ROI(Region of Interest)是图像中需要特别关注的区域。

ROI操作技巧

# 直接选择矩形区域
roi = img[100:300, 200:400]  # y1:y2, x1:x2# 在原始图像上绘制ROI框
cv2.rectangle(img, (200, 100), (400, 300), (0, 255, 0), 2)# 处理ROI区域(例如转换为灰度)
roi_gray = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY)

六、图像添加水印:版权保护技术

水印技术可分为可见水印和不可见水印。

1. 三步骤:

  • 模板输入:使用模板输入所输入的图片其实是作为要添加的水印,有了水印的彩色图之后,我们需要用它来制作一个掩模,这就用到了灰度化和二值化,即先灰度化后二值化,这就得到了带有水印图案的掩模。
  • 与运算:有了模板的掩膜后(也就是二值化图),在要添加水印的图像中,根据掩膜的大小切割出一个ROI区域,也就是要添加水印的区域,让其与模板的掩膜进行与运算。与运算的过程中,只要有黑色像素,那么得到的结果图中的对应位置也会是黑色像素。由于模板的掩膜中目标物体的像素值为黑色,所以经过与运算后,就会在ROI区域中得到模板图的形状。
  • 图像融合:将模板的形状添加到水印区域之后,就可以将该图像与原始的模板图进行图像融合。该组件的目的就是将图像对应的数组中的对应元素进行相加(一定要注意这里的两个数组是规格相同的,也就是说要么都是灰度图,要么都是彩图),其过程如下图所示。

2. 可见水印实现

# 读取水印图片
watermark = cv2.imread("watermark.png", cv2.IMREAD_UNCHANGED)# 调整水印大小
watermark = cv2.resize(watermark, (200, 100))# 提取alpha通道
watermark_img = watermark[:, :, :3]
alpha = watermark[:, :, 3] / 255.0# 创建叠加区域
roi = img[10:110, 10:210]# 混合图像
for c in range(3):roi[:, :, c] = (1 - alpha) * roi[:, :, c] + alpha * watermark_img[:, :, c]

3. 完整示例:

import cv2# 读图
bg = cv2.imread('../images/bg.png')
logo = cv2.imread('../images/logohq.png')
h, w = logo.shape[0:2]   # h, w
roi = bg[0:h, 0:w]# 转为灰度图
gray = cv2.cvtColor(logo, cv2.COLOR_BGR2GRAY)# 二值化
# 黑 logo 白底(阈值法 小于阈值的变黑,大于阈值的设maxval/变白)   与上背景
_, mask1 = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY)
bg1 = cv2.bitwise_and(roi, roi, mask=mask1)# 白 logo黑底(反阈值法  大于阈值变黑,小于阈值的设maxval/变白)  与上 logo
_, mask2 = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY_INV)
bg2 = cv2.bitwise_and(logo, logo, mask=mask2)# 融合  两个结果相加
roi[:] = cv2.add(bg1,bg2)  # 直接对 roi 修改,就能实现原背景改变,因为切片出来的 roi和原背景变量指向内存同一块地址
# dst = cv2.add(bg1,bg2)
# roi[:] = dstcv2.imshow('mask1', mask1)
cv2.imshow('bg1', bg1)
cv2.imshow('mask2', mask2)
cv2.imshow('bg2', bg2)
cv2.imshow('roi', roi)
cv2.imshow('bg', bg)cv2.waitKey(0)
cv2.destroyAllWindows()

七、图像噪点消除:提升图像质量

噪声是图像中随机出现的像素值变化,常见滤波方法如下:

1. 均值滤波

  • 原理:取邻域内像素的平均值
  • 效果:消除高斯噪声,但模糊边缘
blur = cv2.blur(img, (5, 5))

2. 高斯滤波

  • 原理:加权平均,中心点权重最高
  • 效果:有效消除高斯噪声
gaussian = cv2.GaussianBlur(img, (5, 5), 0)

3. 中值滤波

  • 原理:取邻域内像素的中值
  • 效果:消除椒盐噪声,保留边缘
median = cv2.medianBlur(img, 5)

4. 双边滤波

  • 原理:同时考虑空间距离和像素值差异
  • 效果:保留边缘同时减少噪声
bilateral = cv2.bilateralFilter(img, 9, 75, 75)

5. 滤波器选择指南

噪声类型推荐滤波器参数示例
高斯噪声高斯滤波(5,5), σ=0
椒盐噪声中值滤波内核大小=5
边缘保护双边滤波d=9, σColor=75, σSpace=75

6. 完整示例:

import cv2# 读图
lvbo2 = cv2.imread('../images/lvbo2.png')
lvbo3 = cv2.imread('../images/lvbo3.png')# 均值滤波
dst1 = cv2.blur(lvbo2,(3,3))# 方框滤波  底层使用饱和运算 最大255 及白的很多
dst2 = cv2.boxFilter(lvbo2,-1,(3,3),normalize=False)# 高斯滤波
dst3 = cv2.GaussianBlur(lvbo2,(3,3),1)# 中值滤波  非线性(逻辑操作)
dst4 = cv2.medianBlur(lvbo3,3)# 双边滤波
dst5 = cv2.bilateralFilter(lvbo2,7,75,75)cv2.imshow('lvbo2',lvbo2)
# cv2.imshow('lvbo3',lvbo3)
cv2.imshow('dst1',dst1)
# cv2.imshow('dst2',dst2)
# cv2.imshow('dst3',dst3)
# cv2.imshow('dst4',dst4)
cv2.imshow('dst5',dst5)cv2.waitKey(0)
cv2.destroyAllWindows()

图像预处理综合应用

def advanced_preprocessing(image_path):# 1. 读取图像img = cv2.imread(image_path)# 2. 透视变换矫正src_pts = np.float32([[58, 72], [375, 65], [35, 392], [400, 398]])dst_pts = np.float32([[0, 0], [500, 0], [0, 600], [500, 600]])M = cv2.getPerspectiveTransform(src_pts, dst_pts)corrected = cv2.warpPerspective(img, M, (500, 600))# 3. 降噪处理denoised = cv2.bilateralFilter(corrected, 9, 75, 75)# 4. 创建ROI区域roi = denoised[100:400, 150:350]# 5. 添加水印watermark = cv2.imread("watermark.png", cv2.IMREAD_UNCHANGED)watermark = cv2.resize(watermark, (100, 50))roi_watermark = denoised[10:60, 10:110]alpha = watermark[:, :, 3] / 255.0for c in range(3):roi_watermark[:, :, c] = alpha * watermark[:, :, c] + (1 - alpha) * roi_watermark[:, :, c]return denoised

总结

  1. 插值选择:实时系统用最近邻,质量优先用双三次
  2. 边缘填充:反射101(BORDER_REFLECT_101)效果最自然
  3. 透视变换:确保四个点形成凸四边形
  4. 掩膜应用:结合阈值法创建精确掩膜
  5. 噪声消除
    • 椒盐噪声 → 中值滤波
    • 高斯噪声 → 高斯滤波
    • 边缘保护 → 双边滤波

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/93368.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/93368.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/93368.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MongoDB的内存和核心数对于运行效率的影响

在 MongoDB 线上生产环境中,CPU(核心) 和 内存 是两大关键硬件资源,它们在不同的操作场景下发挥着核心作用,共同影响着数据库的性能、稳定性和扩展性。理解它们的作用场景至关重要,是容量规划、性能优化和故…

自己的SAPGUI尝试

为满足用户需求,博主做了一个台账管理程序,尝试用自己的程序做GUI,用SAP 系统做数据库。 运行了半年,程序很nice,用户每天都在高效的使用,已经有十几万的数据。 总结一下这次自己的GUI尝试,好处是C# WINFOR…

高效处理 JSON 数据:JsonUtil 工具类全方位解析与实战

在现代软件开发中,JSON(JavaScript Object Notation)已成为数据交换的“通用语言”——从前后端接口通信到微服务数据交互,从配置文件解析到日志格式化,几乎所有场景都离不开JSON的处理。然而,原生JSON框架(如FastJSON、Jackson)的API往往需要大量重复代码,且空指针、…

Python 库手册:xmlrpc.client 与 xmlrpc.server 模块

xmlrpc.client 和 xmlrpc.server 是 Python 标准库中用于构建基于 XML-RPC 协议的远程过程调用(RPC)通信模块。xmlrpc.client 用于编写客户端程序,向远程服务器发起方法调用。xmlrpc.server 用于编写服务器端,暴露本地方法供远程客…

渲染篇(一):从零实现一个“微型React”:Virtual DOM的真面目

渲染篇(一):从零实现一个“微型React”:Virtual DOM的真面目 引子:前端性能的“永恒之问” 在前面两章中,我们已经奠定了坚实的架构基础。我们用“任务调度器”建立了声明式和模块化的编程范式,并通过对比MVC等模式论…

SWC 深入全面讲解

一、核心功能与原理 1. 高性能编译 Rust 架构优势:SWC 基于 Rust 编写,利用 Rust 的性能和并发性优势,编译速度比 Babel 快约 20 倍,比 TypeScript 编译器更快。并行编译:支持多线程并行处理,在四核基准测试…

XML Expat Parser:深入解析与高效应用

XML Expat Parser:深入解析与高效应用 引言 XML(可扩展标记语言)作为一种广泛使用的标记语言,在数据交换、存储和表示中扮演着重要角色。XML Expat Parser 是一个高性能、可扩展的XML解析库,广泛应用于各种编程语言中。本文将深入探讨XML Expat Parser 的原理、特性以及…

【Python】自动化GIT提交

在日常开发中,我们经常需要频繁地向 Git 仓库提交代码。虽然 git add、git commit、git push 这几个命令并不复杂,但重复操作容易出错,也浪费时间。本文将介绍如何使用 Python 脚本自动化完成 Git 提交流程,让开发更高效&#xff…

基于Qlearning强化学习的水下无人航行器路径规划与避障系统matlab性能仿真

目录 1.引言 2.算法仿真效果演示 3.数据集格式或算法参数简介 4.算法涉及理论知识概要 5.参考文献 6.完整算法代码文件获得 1.引言 水下无人航行器 (Autonomous Underwater Vehicle, AUV) 的路径规划与避障是海洋探索、资源开发和军事应用中的关键技术。传统的路径规划方…

模块自由拼装!Python重构DSSAT作物模块教程(以杂交水稻为例)

基于过程的作物生长模型(Process-based Crop Growth Simulation Model)在模拟作物对气候变化的响应与适应、农田管理优化、作物品种和株型筛选、农业碳中和、农田固碳减排等领域扮演着越来越重要的作用。Decision Support Systems for Agrotechnology Tr…

Java项目接口权限校验的灵活实现

引言 在Java Web开发中,接口权限校验是保护系统资源安全的关键机制。本文将介绍一种灵活、可配置的接口权限校验方案,通过注解驱动和拦截器实现,既能保证安全性,又能灵活控制哪些接口需要校验。 设计思路 实现方案的核心设计要点&…

瀚高DB兼容MySQL if函数

文章目录环境症状问题原因解决方案环境 系统平台:Linux x86-64 Red Hat Enterprise Linux 7 版本:4.5 症状 MySQL if函数在瀚高DB当中没有,源应用在用到if函数时,就会报if函数不存在的错误信息。为此,我们需要根据业…

基于深度学习的胸部 X 光图像肺炎分类系统(六)

目录 结果指标解读 一、为什么选择这些指标? 二、各指标的定义和解读 1. 准确率(Accuracy) 2. 损失(Loss) 3. 精确率(Precision) 4. 召回率(Recall) 三、这些指标…

区块链性能优化策略:从理论到实践

目录 区块链性能优化策略:从理论到实践 1. 引言:区块链性能的挑战 2. 性能评估指标 2.1 核心性能指标 2.2 性能瓶颈分析 3. 分层优化策略 3.1 网络层优化 3.1.1 Gossip协议改进 3.1.2 网络分片 3.2 共识层优化 3.2.1 PBFT优化 3.3 数据层优化 3.3.1 状态树优化 3.3.2 区块数据…

【VLLM】open-webui部署模型全流程

目录 前言 一、租用服务器到服务器连接VScode全流程(可选) 二、下载模型到本地服务器 2.1 进入魔塔社区官网 2.2 选择下载模型 2.3 执行下载 三、部署VLLM 3.1 参考vllm官网文档 3.2 查看硬件要求 3.3 安装vLLM框架 3.4 启动模型服务 方法1:直接启动下载的本地模…

办公自动化入门:如何高效将图片整合为PDF文档

将多张图片合并到一个PDF文件中可以帮助保持特定的顺序和布局,同时确保图像的质量不会因为格式转换而下降。它是免费,不限次数,批量导入也毫无压力。操作堪比发朋友圈:拖图进来 → 选个纸张尺寸 → 点击转换 → 指定保存路径&…

使用宝塔面板搭建 PHP 环境开发一个简单的 PHP 例子

目录一、引言二、准备工作2.1 服务器选择2.2 下载安装宝塔面板三、使用宝塔面板搭建 PHP 环境3.1 登录宝塔面板3.2 选择 Web Server3.3 安装 PHP3.4 安装 MySQL 数据库四、开发一个简单的 PHP 例子4.1 创建 PHP 文件4.2 编写 PHP 代码4.3 设置站点4.4 访问 PHP 页面五、常见问题…

AWS WebRTC:我们的业务模式

拉流、卡录基本流程 设备端(摄像机) 与 App端 是通过 AWS KVS WebRTC 信令服务进行“点对点连接”的,真正的媒体数据(音视频)是通过 WebRTC 的 ICE 通道(P2P 或 TURN)直接传输的,而不…

使用Python,OpenCV,K-Means聚类查找图像中最主要的颜色

使用Python,OpenCV,K-Means聚类查找图像中最主要的颜色 分别把跑图聚类选取1, 2, 3,4, 5, 6, 7,8, 9种主要颜色并绘制colormap颜色图; 效果图 分别把跑图聚类选取3,4, 5,7,9种主要颜色并绘制…

DBAPI 实现分页查询的两种方法

DBAPI 实现分页查询的两种方法 背景 在进行分页查询时,用户通常需要传入当前页码 pageNo 和每页显示的条数 pageSize 参数。根据这两个参数,我们可以从数据库中查询出当前页的数据。以 MySQL 为例,分页查询的 SQL 语句如下: se…