zoukankan      html  css  js  c++  java
  • 东南大学《数字图像处理》课程作业 3

    说明.pdf.1

    说明.pdf.2

    程序代码

    # coding: utf-8
    
    '''
    东南大学《数字图像处理》课程 作业3 - 灰度图放大
    09017227 卓旭 written with Python 3
    
    本程序内灰度图像作为二维数组,存储顺序为[行][列],像素点坐标表示为img[x][y],坐标系为
    O--------> [y axis]
    |
    |
    V [x axis]
    '''
    
    import imageio
    import numpy as np
    import cv2 # OpenCV仅用于显示图片,未使用其中的resize函数
    
    IMAGE_PATH='./Img_Zoom.bmp'
    ZOOM_IN_RATE=5
    
    '''
      读入灰度图像,转为二维numpy数组
    '''
    def readImage(imagePath):
      return imageio.imread(imagePath)
    
    '''
      利用放大倍率计算目标图像在原图像的对应视区,返回四元组 (左上角x坐标, 左上角y坐标, 宽度, 高度)
    '''
    def getViewport(sourceImage, zoomInRate):
      centerX, centerY = list(map(lambda x: x / 2, sourceImage.shape))
      # width, height = list(map(lambda x: x / zoomInRate, sourceImage.shape))
      height, width = list(map(lambda x: x / zoomInRate, sourceImage.shape)) # 这里之前写错了,这次提交修改
      leftTopX, leftTopY = centerX - height / 2, centerY - width / 2
      return (leftTopX, leftTopY, width, height)
    
    '''
      最近邻插值
    '''
    def nearestInterp(sourceImage, zoomInRate):
      leftTopX, leftTopY, _, _ = getViewport(sourceImage, ZOOM_IN_RATE)
      targetImage = np.zeros(sourceImage.shape, dtype=np.uint8)  # 生成全0目标图像,准备填充,数据类型为8bit数
      # 循环目标图像
      for i in range(targetImage.shape[0]):
        for j in range(targetImage.shape[1]):
          # 目标图像中一像素的步进,在原图像中相当于 1/zoomInRate 像素的步进
          # 利用四舍五入,自带取最近邻像素点的效果。半像素是分界线
          targetImage[i][j] = sourceImage[round(i / zoomInRate + leftTopX)][round(j / zoomInRate + leftTopY)]
      return targetImage
    
    '''
      双线性插值
    '''
    def bilinearInterp(sourceImage, zoomInRate):
      leftTopX, leftTopY, _, _ = getViewport(sourceImage, ZOOM_IN_RATE)
      targetImage = np.zeros(sourceImage.shape, dtype=np.uint8)  # 生成全0目标图像,准备填充,数据类型为8bit数
      F = lambda point: sourceImage[point[0]][point[1]] # 返回原图指定坐标处的灰度值
      # 循环目标图像
      for i in range(targetImage.shape[0]):
        for j in range(targetImage.shape[1]):
          # 目标图像中一像素的步进,在原图像中相当于 1/zoomInRate 像素的步进
          # 算出原图像四个插值数据点的坐标
          p00 = [int(i / zoomInRate + leftTopX), int(j / zoomInRate + leftTopY)]
          p01 = [int(i / zoomInRate + leftTopX), int(j / zoomInRate + leftTopY) + 1]
          p10 = [int(i / zoomInRate + leftTopX) + 1, int(j / zoomInRate + leftTopY)]
          p11 = [int(i / zoomInRate + leftTopX) + 1, int(j / zoomInRate + leftTopY) + 1]
          # 当前点在原图像的坐标
          p = [i / zoomInRate + leftTopX, j / zoomInRate + leftTopY]
          # 假设四个插值数据点的权重均相同,该公式的推导请看附带文档
          x0 = p00[0]; x1 = x0 + 1; y0 = p00[1]; y1 = y0 + 1; x = p[0]; y = p[1]
          targetImage[i][j] = (x1 - x) * (y1 - y) * F(p00) + 
                              (x1 - x) * (y - y0) * F(p01) + 
                              (x - x0) * (y1 - y) * F(p10) + 
                              (x - x0) * (y - y0) * F(p11)
      return targetImage
    
    if __name__ == '__main__':
      sourceImage = readImage(IMAGE_PATH)
      print("计算最近邻插值中...")
      targetImage1 = nearestInterp(sourceImage, ZOOM_IN_RATE)
      print("计算双线性插值中...")
      targetImage2 = bilinearInterp(sourceImage, ZOOM_IN_RATE)
      print("计算完成,开始依次显示")
      cv2.imshow("nearestInterp", targetImage1)
      cv2.waitKey(0)
      imageio.imwrite('nearestInterp.bmp', targetImage1)
      print("最近邻插值保存成功")
      cv2.imshow("bilinearInterp", targetImage2)
      imageio.imwrite('bilinearInterp.bmp', targetImage2)
      print("双线性插值保存成功")
      cv2.waitKey(0)
    
  • 相关阅读:
    php上传文件大小修改
    flex布局
    restful
    mysql之windows忘记密码
    mysql常用命令
    比较级浅析1
    一般副词的位子
    still讲解
    英语学习法
    as的如下用法
  • 原文地址:https://www.cnblogs.com/zxuuu/p/14387175.html
Copyright © 2011-2022 走看看