【FPGA图像处理实战】- 图像镜像

作者:FPGA入门到精通

图像的镜像变换是图像处理中一种基本的几何变换操作,它涉及将图像沿着一个或多个坐标轴进行翻转。

本文将详细介绍图像镜像算法的基本原理、Python实现以及FPGA实现。

一、图像镜像算法知识

图像镜像算法包括水平镜像、垂直镜像和对角镜像。

下面的数学计算,均以图像的左上角顶点为原点,图像的宽为W,图像的高为H,设原始图像的任意点为P0(x0,y0),变换后的新点为P(x,y),记w = W - 1,h = H -1。

注意数学公式里,为什么是H-1、W-1?,因为图像的原点是(0, 0),即都是从0开始。

1、水平镜像

在水平镜像变换中,图像的每个点关于y轴(即垂直轴)进行翻转。

变换后,图像的左半部分和右半部分互为镜像。

用数学公式表示,则变换式为

y = y0、x = w - x0

矩阵变换公式为

矩阵变换公式1.png

2、垂直镜像

与水平镜像相对,垂直镜像变换是将图像的每个点关于x轴(即水平轴)进行翻转。

变换后,图像的上半部分和下半部分互为镜像。

用数学公式表示,则变换式为

y = h -y0、x = x0

矩阵变换公式为

矩阵变换公式2.png

3、对角镜像

对角镜像变换同时沿着x轴和y轴翻转图像,也就水平垂直镜像。

变换后,图像的每个点都将映射到其关于图像中心点对称的位置。

用数学公式表示,则变换式为

y = h -y0、x = w - x0

矩阵变换公式为

矩阵变换公式3.png

二、Python实现

直接调用矩阵运算变换即可实现。

1、源代码

import cv2
import numpy as np

img = cv2.imread('test1.png')
h, w, c = img.shape

fliped_x_image = np.zeros((h, w, 3), dtype=np.uint8)
fliped_y_image = np.zeros((h, w, 3), dtype=np.uint8)
fliped_xy_image = np.zeros((h, w, 3), dtype=np.uint8)

# 水平镜像
flip_matrix = np.array([[-1, 0, 0], [0, 1, 0], [w - 1, 0, 1]])
for y in range(h):
    for x in range(w):
        flip_x, flip_y, _ = np.dot([x, y, 1], flip_matrix)
        fliped_x_image[flip_y, flip_x] = img[y, x]

# 垂直镜像
flip_matrix = np.array([[1, 0, 0], [0, -1, 0], [0, h - 1, 1]])
for y in range(h):
    for x in range(w):
        flip_x, flip_y, _ = np.dot([x, y, 1], flip_matrix)
        fliped_y_image[flip_y, flip_x] = img[y, x]

# 对角镜像
flip_matrix = np.array([[1, 0, 0], [0, -1, 0], [0, h - 1, 1]])
for y in range(h):
    for x in range(w):
        flip_x, flip_y, _ = np.dot([x, y, 1], flip_matrix)
        fliped_xy_image[flip_y, flip_x] = img[y, x]

# 显示图像
cv2.namedWindow("orignal", 0)
cv2.resizeWindow("orignal", 300, 180)  # 设置窗口大小
cv2.namedWindow("hor_flip", 0)
cv2.resizeWindow("hor_flip", 300, 180)  # 设置窗口大小
cv2.namedWindow("ver_flip", 0)
cv2.resizeWindow("ver_flip", 300, 180)  # 设置窗口大小
cv2.namedWindow("diag_flip", 0)
cv2.resizeWindow("diag_flip", 300, 180)  # 设置窗口大小
cv2.imshow('orignal', img)
cv2.imshow('hor_flip', fliped_x_image)
cv2.imshow('ver_flip', fliped_y_image)
cv2.imshow('diag_flip', fliped_xy_image)

cv2.waitKey(0)
cv2.destroyAllWindows()

2、测试结果图像

测试结果图像.png

三、FPGA实现

FPGA实现镜像变换算法,需要使用行缓存和帧缓存,从缓存中读取数据时,按照变换公式,计算读地址逻辑即可,这里分享下FPGA设计思路。

1、水平镜像

水平镜像,只涉及水平方向的数据顺序变换,只需要两个行缓存即可实现,读取地址不是顺序的,只能使用BRAM或URAM资源实现。

关键逻辑:乒乓操作,使用两个行缓存,写入数据时,按照一行数据从左到右依次写入,读取数据时,按照从右到左的逆序读数据即可。

源码暂不分享,可以看下FPGA实现效果:

FPGA实现效果.png

2、垂直镜像

垂直镜像,涉及垂直方向的数据顺序变换,需要两个帧缓存即可实现,可以使用DDR实现。

关键逻辑:乒乓操作,使用两个帧缓存,写入数据时,按照从上到下依次写入每行数据,读取数据时,按照从下到上逆序读取每行数据。

源码暂不分享,可以看下FPGA实现效果:

FPGA实现效果1.png

3、对角镜像

对角镜像,涉及垂直方向和水平方向的数据顺序变换,只需要两个帧缓存即可实现,可以使用DDR实现。

关键逻辑:乒乓操作,使用两个帧缓存,写入数据时,按照从上到下依次写入每行数据,读取数据时,按照从下到上逆序读取每行数据,而且读取每行数据时,都是按照从右到左的顺序读取。

源码暂不分享,可以看下FPGA实现效果:

FPGA实现效果2.png

最新文章

最新文章