图像处理中的边缘填充:原理与实践

目录

一、为什么需要边缘填充?

二、边缘填充方法

[4.1 边界复制(BORDER_REPLICATE)](#4.1 边界复制(BORDER_REPLICATE))

[4.2 边界反射(BORDER_REFLECT)](#4.2 边界反射(BORDER_REFLECT))

[4.3 边界反射101(BORDER_REFLECT_101)](#4.3 边界反射101(BORDER_REFLECT_101))

[4.4 边界常数(BORDER_CONSTANT)](#4.4 边界常数(BORDER_CONSTANT))

[4.5 边界包裹(BORDER_WRAP)](#4.5 边界包裹(BORDER_WRAP))

三、完整代码

四、总结


在图像处理中,边缘填充是一个常见的操作,尤其是在对图像进行旋转、缩放或变换时。填充边缘可以避免图像边界出现空白区域,从而保持图像的完整性。本文将详细介绍五种常用的边缘填充方法,并通过代码示例展示它们的实际应用。

一、为什么需要边缘填充?

在对图像进行旋转或变换时,原图像的某些部分可能会超出目标图像的边界,导致目标图像中出现空白区域。例如,当我们将一张图片逆时针旋转45度时,原图的四个顶点在旋转后的图像中已经看不到了,而旋转后的图像的四个顶点区域实际上是空白的。为了填补这些空白区域,我们需要对边缘进行填充。

以下是一个简单的例子:

|----------------------------------------------------------------------------|----------------------------------------------------------------------------|
| 原图: | 旋转后的图: |
| | |

可以看到,旋转后的图像中出现了黑色的空白区域。为了避免这种情况,我们需要对这些空白区域进行填充。

二、边缘填充方法

OpenCV提供了多种边缘填充方法,每种方法都有其独特的填充方式和应用场景。以下是五种常用的边缘填充方法:

4.1 边界复制(BORDER_REPLICATE)

原理

边界复制会将边界处的像素值进行复制,然后作为边界填充的像素值。填充后的图像四周的像素值与边界像素值相同。

示例

原图与填充后的图像对比如下:

|----------------------------------------------------------------------------|----------------------------------------------------------------------------|
| 原图 | 边界复制填充 |
| | |

代码实现

python 复制代码
import cv2
import numpy as np

def test_edge_filling():
    img = cv2.imread("./src/cat.png")
    h, w, c = img.shape
    scale = 0.5
    m = cv2.getRotationMatrix2D((w // 2, h // 2), 45, scale)
    frame = (w, h)
    
    img_replicate = cv2.warpAffine(img, m, frame, borderMode=cv2.BORDER_REPLICATE)
    cv2.imshow("Original Image", img)
    cv2.imshow("Replicate Border", img_replicate)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

if __name__ == '__main__':
    test_edge_filling()

4.2 边界反射(BORDER_REFLECT)

原理

边界反射会根据原图的边缘进行反射填充。填充后的图像在边界处形成镜像效果。

示例

原图与填充后的图像对比如下:

|----------------------------------------------------------------------------|----------------------------------------------------------------------------|
| 原图 | 边界反射填充 |
| | |

代码实现

python 复制代码
img_reflect = cv2.warpAffine(img, m, frame, borderMode=cv2.BORDER_REFLECT)
cv2.imshow("Reflect Border", img_reflect)

4.3 边界反射101(BORDER_REFLECT_101)

原理

与边界反射不同的是,边界反射101不再反射边缘的像素点,而是从倒数第二个像素点开始反射。

示例

原图与填充后的图像对比如下:

|----------------------------------------------------------------------------|----------------------------------------------------------------------------|
| 原图 | 边界反射101 |
| | |

代码实现

python 复制代码
img_reflect_101 = cv2.warpAffine(img, m, frame, borderMode=cv2.BORDER_REFLECT_101)
cv2.imshow("Reflect 101 Border", img_reflect_101)

4.4 边界常数(BORDER_CONSTANT)

原理

边界常数填充会用指定的常量值填充空白区域。默认的填充常数值为0(黑色),但也可以指定其他颜色。

示例

原图与填充后的图像对比如下:

|----------------------------------------------------------------------------|----------------------------------------------------------------------------|
| 原图 | 边界常数填充 |
| | |

代码实现

python 复制代码
img_constant = cv2.warpAffine(img, m, frame, borderMode=cv2.BORDER_CONSTANT, borderValue=(0, 0, 127))
cv2.imshow("Constant Border", img_constant)

4.5 边界包裹(BORDER_WRAP)

原理

边界包裹会将图像的边界部分"包裹"到另一侧,形成循环效果。

示例

原图与填充后的图像对比如下:

|----------------------------------------------------------------------------|----------------------------------------------------------------------------|
| 原图 | 边界反射101 |
| | |

代码实现

python 复制代码
img_wrap = cv2.warpAffine(img, m, frame, borderMode=cv2.BORDER_WRAP)
cv2.imshow("Wrap Border", img_wrap)

三、完整代码

python 复制代码
import cv2
import numpy as np

# 填充方式
# 边界复制(BORDER_REPLICATE): 复制边界像素值
# 边界反射(BORDER_REFLECT): 以边界为对称轴,反射填充
# 边界反射101(BORDER_REFLECT_101): 以边界为对称轴,反射填充,但首尾像素不重复
# 边界常数(BORDER_CONSTANT): 用指定常量填充
# 边界包裹(BORDER_WRAP): 以边界为对称轴,循环填充
def test001():
    img = cv2.imread("./src/cat.png")
    h, w, c = img.shape
    scale = 0.5
    m = cv2.getRotationMatrix2D((w // 2, h // 2), 45, scale)
    frame=(w,h)
    # 如果scale后的图像比frame小 就会有部分像素没值 就会进行填充
    img_replicate=cv2.warpAffine(img,m,frame,borderMode=cv2.BORDER_REPLICATE)
    img_reflect=cv2.warpAffine(img,m,frame,borderMode=cv2.BORDER_REFLECT)
    img_reflect_101=cv2.warpAffine(img,m,frame,borderMode=cv2.BORDER_REFLECT_101)
    img_constant=cv2.warpAffine(img,m,frame,borderMode=cv2.BORDER_CONSTANT,borderValue=(0,0,127))
    img_wrap=cv2.warpAffine(img,m,frame,borderMode=cv2.BORDER_WRAP)
    
    cv2.imshow("img",img)
    cv2.imshow("img_replicate",img_replicate)
    cv2.imshow("img_reflect",img_reflect)
    cv2.imshow("img_reflect_101",img_reflect_101)
    cv2.imshow("img_constant",img_constant)
    cv2.imshow("img_wrap",img_wrap)
    cv2.waitKey(0)

if __name__ == '__main__':
    test001()

四、总结

本文介绍了五种常用的边缘填充方法:边界复制、边界反射、边界反射101、边界常数和边界包裹。每种方法都有其独特的应用场景和效果。在实际应用中,可以根据具体需求选择合适的填充方法。

  • 边界复制:适合需要保持边界像素值不变的场景。

  • 边界反射:适合需要镜像效果的场景。

  • 边界反射101:适合需要更自然的镜像效果的场景。

  • 边界常数:适合需要特定颜色填充的场景。

  • 边界包裹:适合需要循环效果的场景。

相关推荐
发哥来了6 小时前
东莞AI培训课程横向对比:五家机构教学与就业质量评测
大数据·人工智能·机器学习·ai·aigc
AI医影跨模态组学6 小时前
(综述)J Transl Med 浙江大学医学院附属第二医院等团队:放射组学在胶质母细胞瘤复发中的应用:预测、定位及与治疗相关效应鉴别的进展
人工智能·深度学习·医学·医学影像·影像组学
神工坊6 小时前
新闻︱神工坊受邀出席无锡人工智能产业园“AI赋能研发设计”主题活动,共探算力与AI时代下的CAE范式革新
人工智能·ai·hpc·cfd·cae·求解加速·智能修模
我是发哥哈6 小时前
东莞AI培训主流方案横向评测:5大选型维度解析
大数据·人工智能·学习·机器学习·chatgpt·ai编程
千寻girling6 小时前
机器学习 | 感知机 | 尚硅谷学习
人工智能·学习·机器学习
南河的南6 小时前
RAG项目总结
人工智能
大模型真好玩6 小时前
LangChain DeepAgents 速通指南(八)—— DeepAgents流式输出详解
人工智能·langchain·agent
码上掘金6 小时前
基于 YOLO 的小麦麦穗检测系统的设计与实现
人工智能·yolo·语言模型
沪漂阿龙6 小时前
AI Agent爆火,但你真的懂LangChain吗?——大模型智能体开发完全指南
人工智能·langchain
可爱の小公举6 小时前
Java 后端程序员转 AI Agent 工程师:一条可执行学习路线
java·人工智能·学习