邊緣檢測和圖像插值(生成皮卡丘的輪廓!&& 放大圖片n倍!)

一、實驗介紹

(1)實驗目的

  • 掌握邊緣檢測和圖像插值
  • 語言:python

(2)測試圖像

在這裏插入圖片描述

(3)實驗內容

  • 編寫程序實現對圖片的邊緣檢測。
  • 編寫程序實現對圖像的插值

二、編寫程序實現對圖片的邊緣檢測

(1)canny邊緣檢測代碼

  • 編寫程序實現線性、高斯核、拉普拉斯核的的SVM分類器設計。
import cv2
img = cv2.imread("picaqu.jpg", 0)
cv2.imwrite("canny.jpg", cv2.Canny(img, 200, 300))
cv2.imshow("canny", cv2.imread("canny.jpg"))
cv2.waitKey()
cv2.destroyAllWindows()

(2)結果

在這裏插入圖片描述

(3)分析

  • 可以發現canny邊緣檢測算子的效果較爲不錯

三、最近鄰插值

  • 將圖像由500x283增大爲2048x1160

(1)代碼

import cv2
import numpy as np
IMG_PATH = "./picaqu.jpg"
NUM2 = 2048
NUM1 = int(NUM2 * 283 / 500)
def function(img):
    height, width, channels = img.shape
    emptyImage = np.zeros((NUM1, NUM2, channels), np.uint8)
    sh = NUM1 / height
    sw = NUM2 / width
    for i in range(NUM1):
        for j in range(NUM2):
            x = int(i / sh)
            y = int(j / sw)
            emptyImage[i, j] = img[x, y]
    return emptyImage
img = cv2.imread(IMG_PATH)
zoom = function(img)
cv2.imwrite("./nearest neighbor.jpg", zoom)
print('完成')

(2)結果

在這裏插入圖片描述

四、雙線性插值

  • 將圖像由500x283增大爲2048x1160

(1)代碼

import cv2
import numpy as np
IMG_PATH = "./picaqu.jpg"
NUM2 = 2048
NUM1 = int(NUM2 * 283 / 500)
def function(img):
    height, width, channels = img.shape
    emptyImage = np.zeros((NUM1, NUM2, channels), np.uint8)
    value = [0, 0, 0]
    sh = NUM1 / height
    sw = NUM2 / width
    for i in range(NUM1):
        for j in range(NUM2):
            x = i / sh
            y = j / sw
            p = (i + 0.0) / sh - x
            q = (j + 0.0) / sw - y
            x = int(x) - 1
            y = int(y) - 1
            for k in range(3):
                if x + 1 < NUM1 and y + 1 < NUM2:
                    value[k] = int(
                        img[x, y][k] * (1 - p) * (1 - q) + img[x, y + 1][k] * q * (1 - p) + img[x + 1, y][k] * (
                                    1 - q) * p + img[x + 1, y + 1][k] * p * q)
            emptyImage[i, j] = (value[0], value[1], value[2])
    return emptyImage
img = cv2.imread(IMG_PATH)
zoom = function(img)
cv2.imwrite("./Bilinear Interpolation.jpg", zoom)
# cv2.waitKey(0)
print('完成')

(2)結果

在這裏插入圖片描述

五、雙立方插值

  • 將圖像由500x283增大爲2048x1160

(1)代碼

import cv2
import numpy as np

IMG_PATH = "./picaqu.jpg"
NUM2 = 2048
NUM1 = int(NUM2 * 283 / 500)

def S(x):
    x = np.abs(x)
    if 0 <= x < 1:
        return 1 - 2 * x * x + x * x * x
    if 1 <= x < 2:
        return 4 - 8 * x + 5 * x * x - x * x * x
    else:
        return 0


def function(img, m, n):
    height, width, channels = img.shape
    emptyImage = np.zeros((m, n, channels), np.uint8)
    sh = m / height
    sw = n / width
    for i in range(m):
        for j in range(n):
            x = i / sh
            y = j / sw
            p = (i + 0.0) / sh - x
            q = (j + 0.0) / sw - y
            x = int(x) - 2
            y = int(y) - 2
            A = np.array([
                [S(1 + p), S(p), S(1 - p), S(2 - p)]
            ])
            if x >= m - 3:
                m - 1
            if y >= n - 3:
                n - 1
            if x >= 1 and x <= (m - 3) and y >= 1 and y <= (n - 3):
                B = np.array([
                    [img[x - 1, y - 1], img[x - 1, y],
                     img[x - 1, y + 1],
                     img[x - 1, y + 1]],
                    [img[x, y - 1], img[x, y],
                     img[x, y + 1], img[x, y + 2]],
                    [img[x + 1, y - 1], img[x + 1, y],
                     img[x + 1, y + 1], img[x + 1, y + 2]],
                    [img[x + 2, y - 1], img[x + 2, y],
                     img[x + 2, y + 1], img[x + 2, y + 1]],

                ])
                C = np.array([
                    [S(1 + q)],
                    [S(q)],
                    [S(1 - q)],
                    [S(2 - q)]
                ])
                blue = np.dot(np.dot(A, B[:, :, 0]), C)[0, 0]
                green = np.dot(np.dot(A, B[:, :, 1]), C)[0, 0]
                red = np.dot(np.dot(A, B[:, :, 2]), C)[0, 0]

                # ajust the value to be in [0,255]
                def adjust(value):
                    if value > 255:
                        value = 255
                    elif value < 0:
                        value = 0
                    return value

                blue = adjust(blue)
                green = adjust(green)
                red = adjust(red)
                emptyImage[i, j] = np.array([blue, green, red], dtype=np.uint8)

    return emptyImage


img = cv2.imread(IMG_PATH)
zoom = function(img, NUM1, NUM2)
cv2.imwrite("./cubic.jpg", zoom)
print('完成')

(2)結果

在這裏插入圖片描述

六、結果分析

  • 使用canny邊緣檢測算子所得的結果較好,可以看出所有的邊緣信息都被檢測出來了
  • 圖像插值算法中,最鄰近插值,雙線性插值,雙三次插值效果都較好,能夠很好的放大圖像,得到滿意的結果

參考

無聊之作-圖像插值方法python實現

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