当前位置: 代码网 > it编程>前端脚本>Python > python图像处理实验:图像处理基本操作

python图像处理实验:图像处理基本操作

2024年08月04日 Python 我要评论
我使用的是python,python中的opencv库中包含许多丰富图像处理函数,我们可以方便的直接使用这些封装好的函数,但是对于我们学习这门课程的主要意义不仅仅是会进行图像处理,还要明白图像处理的原理,以及函数实现的过程。图(b)为灰度增强函数,根据函数的映射规则,原始图像的灰度值B映射为灰度值W,原始图像的灰度值W映射为灰度值B;式中:k为原始图像的灰度值f(x,y),t为变换图像的灰度值g(x,y),E()为灰度增强函数。如果flipCode的值大于0,表示绕y轴翻转,对应于实现图像的水平镜像;

实验一:图像处理基本操作

一、实验目的

1、熟悉并掌握matlab工具的使用;

2、实现图像的读取、显示、存储、平移、镜像、放大、缩小及旋转操作;

3、掌握常用的插值方法,并了解其优缺点。

二、实验环境

ide:pycharm

python

三、实验内容(题目、相关知识(函数,原理…)、代码、实验结果)

1、读入一幅rgb图像(自选),变换为灰度图像和二值图像,并在同一个窗口内分别显示rgb图像和灰度图像,注上文字标题,并将结果以文件形式存到磁盘上。

灰度变换属于空域变换增强技术。

目的:

一般成像系统形成图像的亮度有限,对比度不足,使图像的视觉效果差,灰度变换即可有效地改善视觉效果。

概念:

灰度变换是一种点操作,根据原始图像中每个像素的灰度值,按照某种映射规则将其转化为另一灰度值。灰度变换可有效改善图像的视觉效果,变换原理可表示为如式所示:

t = e(k)

式中:k为原始图像的灰度值f(x,y),t为变换图像的灰度值g(x,y),e()为灰度增强函数。

原理:

灰度变换原理可由图来说明,其中,图(a)为原始图像,具有两种灰度级,分别用b和w来表示;图(b)为灰度增强函数,根据函数的映射规则,原始图像的灰度值b映射为灰度值w,原始图像的灰度值w映射为灰度值b;图(c)为变换后的图像。
在这里插入图片描述

灰度变换的关键在于根据增强要求设计灰度映射规则,即设计灰度增强函数。典型灰度变换函数包括:比例线性变换、分段线性变换、非线性变换

图像二值化就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的黑白效果的过程。二值图像每个像素只有两种取值:要么纯黑,要么纯白。由于二值图像数据足够简单,许多视觉算法都依赖二值图像。通过二值图像,能更好地分析物体的形状和轮廓。二值图像也常常用作原始图像的掩模(又称遮罩、蒙版,mask):它就像一张部分镂空的纸,把我们不感兴趣的区域遮掉。进行二值化有多种方式,其中最常用的就是采用阈值法(thresholding)进行二值化。

转换为灰度图像使用函数cvcolor,这里转化为二值图像直接设置阈值判断灰度值大小,如果灰度值大于阈值直接赋值为255,反之赋值为0

实验代码:
在这里插入图片描述

实验结果:
在这里插入图片描述

2、对图像(自选)执行平移、镜像(水平镜像、垂直镜像)放大、缩小及旋转操作,其中放大、旋转操作分别采用最近邻插值及双线性插值方法实现,要求根据算法自己编写代码实现,并分析两种插值方法的优缺点。

(1)平移

图像平移首先定义平移矩阵m,再调用warpaffine()函数实现平移,python函数如下:

m = np.float32([[1, 0, x], [0, 1, y]])

m表示平移矩阵,其中x表示水平平移量,y表示垂直平移量

shifted = cv2.warpaffine(src, m, dsize[, dst[, flags[, bordermode[, bordervalue]]]])

src表示原始图像

m表示平移矩阵

dsize表示变换后的输出图像的尺寸大小

dst为输出图像,其大小为dsize,类型与src相同

flag表示插值方法的组合和可选值

bordervalue表示像素外推法,当bordermode = border_transparent时,表示目标图像中的像素不会修改源图像中的“异常值”。

bordervalue用于边界不变的情况,默认情况下为0
在这里插入图片描述

平移后图像

(2)旋转

旋转前:

x0=rcosb,y0=rsinb

旋转后:

x1=rcos(b-a)=rcosbcosa+rsinbsina=x0cosa+y0sina

y1=rsin(b-a)=rsinbcosa-rcosbsina=-x0sina+y0cosa

一般3-d旋转的变换。将一个空间点p绕一个中心点c旋转可用连续的3个变换来实现:

第1个变换:平移点c到坐标原点。

第2个变换:将p绕原点旋转。

第3个变换:平移点c回到原始位置。

本实验中要求旋转采用双线性插值法

如下为主要算法代码:

import math
import random
import cv2
import numpy as np
def bilinear_rotate(imgarray):
    h, w, channel = imgarray.shape
    pi = math.pi
    theta = random.randint(0,360)
    angle = theta * pi / 180
    matrix1 = np.array([[1, 0, 0],
                        [0, -1, 0],
                        [-0.5 * h, 0.5 * w, 1]])
    matrix2 = np.array([[math.cos(angle), -math.sin(angle), 0],
                        [math.sin(angle), math.cos(angle), 0],
                        [0, 0, 1]])
    matrix3 = np.array([[1, 0, 0],
                        [0, -1, 0],
                        [0.5 * h, 0.5 * w, 1]])
    new_data = np.zeros_like(imgarray,dtype=np.uint8)
    for i in range(h):
        for j in range(w):
            dot1 = np.matmul(np.array([i, j, 1]), matrix1)
            dot2 = np.matmul(dot1, matrix2)
            dot3 = np.matmul(dot2, matrix3)
            new_coordinate = dot3
            new_i = int(math.floor(new_coordinate[0]))
            new_j = int(math.floor(new_coordinate[1]))
            u = new_coordinate[0] - new_i
            v = new_coordinate[1] - new_j
            if new_j>=w or new_i >=h or new_i<1 or new_j<1 or (i+1)>=h or (j+1)>=w:
                continue
            if (new_i + 1)>=h or (new_j+1)>=w:
                new_data[i, j, :] = imgarray[new_i,new_j, :]
            else:
                new_data[i, j, :] = (1-u)*(1-v)*imgarray[new_i,new_j, :] + \
                                   (1-u)*v*imgarray[new_i,new_j+1, :] + \
                                   u*(1-v)*imgarray[new_i+1,new_j, :] +\
                                   u*v*imgarray[new_i+1,new_j+1, :]
    return new_data
image = cv2.imread('asen.jpg')
new_image = bilinear_rotate(image)
cv2.imshow('rotated image', new_image)

运行结果:
在这里插入图片描述

(3)缩放

缩放采用最邻近插值缩放

插值的目的是根据已知的图像的像素值获得未知目标图像的像素值

其中src表示原始图像,tar表示插值得到的目标图像,h和w分别表示图像的高度和宽度。插值的核心是找到(tar_x, tar_y)和(src_x, src_y)的映射关系,从而实现对目标图像的每一个像素点进行赋值。假设目的是将原始图像长度和宽度扩大(3,4)倍,即:

ratio_h = tar_h/src_h = tar_x/src_x = 3

ratio_w = tar_w/src_w = tar_y/src_y = 4

通过上式变形,得到目标图像的像素点和原始图像的像素点映射如下:

tar_x = src_x/ratio_h

tar_y = src_y/ratio_w

知道了像素点之间的映射关系,实现算法就很容易了,算法流程如下:

根据tar_h和tar_w创建目标图像

计算缩放比例因子ratio

遍历目标图像每个像素点,计算映射关系

遍历目标图像每个像素点,使用对应原始图像的对应像素点对其赋值

算法代码:

import cv2
import numpy as np

def test(img, weight_out, height_out):
    # 获取图像的大小
    height_in, weight_in, _ = img.shape
    # 创建输出图像
    outimg = np.zeros((height_out, weight_out, 3), dtype=np.uint8)

    for x in range(height_out - 1):
        for y in range(weight_out - 1):
            # 计算输出图像坐标(i,j)坐标使用输入图像中的哪个坐标来填充
            x_out = round(x * (height_in / height_out))
            y_out = round(y * (weight_in / weight_out))
            # 插值
            outimg[x, y] = img[x_out, y_out]
    return outimg


# 读取图像
img = cv2.imread('asen.jpg')
test = test(img, int(img.shape[1] * 1.5), int(img.shape[0] * 1.5))
# opencv函数
opencv_test = cv2.resize(img, (int(img.shape[1] * 1.5), int(img.shape[0] * 1.5)))

cv2.imshow("nearest neighbor", test)  # 近邻插值缩放后
cv2.imshow("image", img)  # 原图
cv2.waitkey(0)

运行结果:
在这里插入图片描述

(4)镜像

opencv的函数flip()可以实现图像沿x轴翻转、沿y轴翻转、同时沿x轴和y轴翻转,从而实现图像的水平镜像和垂直镜像。

函数()的c++原型如下:

void cv::flip(inputarray src,

outputarray dst,

int flipcode )

如果flipcode的值大于0,表示绕y轴翻转,对应于实现图像的水平镜像;
如果flipcode的值等于0,表示绕x轴翻转,对应于实现图像的垂直镜像;
如果flipcode的值小于0,表示同时绕x轴和y轴翻转,对应于同时实现图像的垂直镜像和水平镜像

运行结果:
在这里插入图片描述

四、实验心得

本次图像处理实验主要是对图像进行了灰度值的变化,以及平移、镜像、放大、旋转等操作。我使用的是python,python中的opencv库中包含许多丰富图像处理函数,我们可以方便的直接使用这些封装好的函数,但是对于我们学习这门课程的主要意义不仅仅是会进行图像处理,还要明白图像处理的原理,以及函数实现的过程。这就要求我们可以不使用库函数的情况下,自己编写相应的插值方法来实现图像的放大缩小等操作。总而言之,图像处理对我们生活方方面面影响巨大,我们学习这门课程要懂得图像处理原理,并运用于实践当中。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com