【數字圖像處理】實驗二:幾何變換與變形(python)

實驗2.1:圖像縮放

實現一個圖像縮放函數,可以對輸入圖像進行任意倍數的縮放;

採用雙線性插值進行重採樣;

X,Y方向的縮放倍數參函數參數的形式傳入;

可以只考慮輸入圖像爲3通道,8位深度的情況;

不能調用圖像處理庫的縮放函數來完成;

void Scale(const MyImage &input, MyImage &output, double sx, double sy);

代碼:

import cv2
import numpy as np
import math

# input:輸入圖像;sx、sy:縮放倍數
def Scale(img, sx, sy):

    # 得到圖像的長、寬
    old_height, old_width = img.shape[:2]
    # 計算新的長、寬
    new_width = round(old_width*sx)
    new_height = round(old_height*sy)

    dst = np.zeros((new_height, new_width, 3), dtype = np.uint8)
    # 雙線性插值法
    for i in range(3):# 通道
        for h in range(new_height):# 高度
            for w in range(new_width):# 寬度
                # 目標在原圖像上的位置
                src_x = (w + 0.5) / sx - 0.5
                src_y = (h + 0.5) / sy - 0.5

                # 計算在原圖像上四個近鄰點的位置
                src_x_0 = int(np.floor(src_x))
                src_y_0 = int(np.floor(src_y))
                src_x_1 = min(src_x_0 + 1, old_width - 1)
                src_y_1 = min(src_y_0 + 1, old_height - 1)

                #雙線性插值
                t0 = (src_x_1 - src_x) * img[src_y_0, src_x_0, i] + (src_x - src_x_0) * img[src_y_0, src_x_1, i]
                t1 = (src_x_1 - src_x) * img[src_y_1, src_x_0, i] + (src_x - src_x_0) * img[src_y_1, src_x_1, i]
                dst[h, w, i] = int((src_y_1 - src_y) * t0 + (src_y - src_y_0) * t1)
    return dst

if __name__ == '__main__':
    # 讀入圖像
    img = cv2.imread("1.jpg")
    # 創建一個窗口
    cv2.namedWindow("Image")
    # 顯示圖像
    cv2.imshow("input_image", img)

    img_out = Scale(img, 0.5, 0.5)

    cv2.imshow('output_image', img_out)
    cv2.waitKey(0)

實驗2.2:圖像變形

[x’, y’]=f([x, y])爲像素座標的一個映射,實現f所表示的圖像形變。f的逆映射爲:

輸入圖像:

輸出:

代碼:

# coding=utf-8
import cv2
import math
import numpy as np

def transform(src):
    # 源圖像寬高
    height, width = src.shape[:2]
    #新建空矩陣存放新圖像
    dst = np.zeros((height, width, 3), dtype=np.uint8)
    for i in range(3):  # 對通道遍歷
        for h in range(height): # 對高遍歷
            for w in range(width): # 對寬遍歷
                #中心歸一化座標
                x = w/(0.5 * width) - 1
                y = h/(0.5 * height) - 1
                # 計算r
                r = math.sqrt(pow(x, 2.0) + pow(y, 2.0))
                # 計算角度
                theta = pow(1 - r, 2.0)
                if r>=1:
                    srcx = x
                    srcy = y
                else:
                    srcx = math.cos(theta)*x - math.sin(theta)*y
                    srcy = math.sin(theta)*x + math.cos(theta)*y
                #中心歸一化還原
                sx = int((srcx + 1) * 0.5 * width)
                sy = int((srcy + 1) * 0.5 * height)
                dst[h, w, i] = src[sy, sx, i]
    return dst

if __name__ == '__main__':
    img_in = cv2.imread('1.jpg')
    img_out = transform(img_in)

    cv2.imshow('input_image', img_in)
    cv2.imshow('output_image', img_out)
    cv2.waitKey(0)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章