Geometric Transformations of Images

จาก Morange Wiki
รุ่นแก้ไขเมื่อ 11:25, 3 สิงหาคม 2559 โดย Patcharapun (คุย | มีส่วนร่วม) (everythin it's gonna be ok)
(ต่าง) ←รุ่นแก้ไขก่อนหน้า | รุ่นแก้ไขล่าสุด (ต่าง) | รุ่นแก้ไขถัดไป→ (ต่าง)

การแปลงรูปตามเลขขาคณิตของรูปภาพ

วัตถุประสงค์

  • เรียนรู้วิธีที่จะเปลี่ยนรูปร่างของไฟล์ภาพตามรูปทรงเลขาคณิต เหมือนกับการ หมุนหรือการแปลง
  • รู้การใช้คำสั่ง cv2.getPerspectiveTransform

รูปร่าง

  • OpenCV จะมีคำสั่งในการเปลี่ยนรูปร่าง 2 คำสั่ง คือ cv2.warpAffine และ cv2.warpPerspective ทั้งหมดนี้คุณสามาระเปลี่ยนรูปร่างได้เกือบครบทุกวิธี โดยหลักการคือ คำสั่ง cv2.warpAffine จะทำให้มีขนาด 2x3 ของรูปร่างเมทริกซ์ ขณะที่ cv2.warpPerspective ให้ขนาด 3x3 ของรูปร่างเมทริกซ์

การสเกล (ย่อ/ขนาย ขนาด)

  • ในการย่อขยาย ขนาดรูปภาพนั้น OpenCV จะมาพิมกับฟังก์ชัั่นชื่อว่า cv2.resize() , ขนาดของรูปภาพนั้นสามารถที่จะย่อหรือขยายด้วยมือเปล่าได้ (Manual)
  • ในการแก้ไขที่แตกต่างออกไปนั้น มีหลายวิธีที่จะทำ เช่นการหดรูป ใช้คำสั่ง cv2.INTER_AREA และ cv2.INTER_CUBIC สำหรับ Slow & cv2.INTER_LINEAR สำหรับซูม โดยปกตินั้นการแก้ไขที่เป็นค่าเริ่มต้นนั้นจะใช้คำสั่ง cv2.INTER_LINEAR สำหรับการ resize
  • สำหรับวิธีย่อขยายรูปนั้น มีวิธีที่สามารถทำได้โดยวิธีต่อไปนี้


import cv2
import numpy  as np

img  = cv2.imread('Something.jpg')

res = cv2.resize(img,None,fx=2, fy=2, interpolation = cv2.INTER_CUBIC)

#หรือ
height , width = img.shape[:2]
res = cv2.resize(img,(2*width, 2*height), interpolation = cv2.INTER_CUBIC)

การแปลงภาพ (ขยับ) Translation

  • การแปลภาพ (Translation) คือการขยับรูปภาพจากจุดนึงไปอีกจุดนึง โดยมีสูตรทางคณิตศาสตร์ คือ
Selection 058.png
  • และสามารถทำได้โดยโมดูล Numpy array of type np.float32 และทำให้อาเรย์นั้นเข้าไปอยู่ในฟังก์ชั่น cv2.warpAffine() ดังตัวอย่างต่อไปนี้ ย้ายแก (x,y) มีค่าเท่ากับ (100,50)


import cv2
import numpy as np

img = cv2.imread('SomethingElse.jpg',0)
row,cols = img.shape

M = np.float32([[1,0,100],[0,1,50]])

cv2.imshow('img',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

การหมุน Rotation

  • การหมุนภาพสำหรับมุม θ คือการเปลี่ยนรูปร่างจากเมตริกซ์ โดยสูตร
Selection 059.png
  • แต่ OpenCV ให้หมุนปรับขนาดโดยมีศูนย์ปรับการหมุนเพื่อให้สามารถหมุนได้ในทุกมุมที่ต้องการ การแก้ไขเปลี่ยนแปลงเมทริกซ์ทำได้โดยสูตรต่อไปนี้
Selection 061.png


  • สำหรับการหาการแปรรูปทางเมตริกซ์นั้น OpenCV ได้สร้างฟังก์ชั่นชื่อว่า cv2.getRotationMatrix2D วิธีใช้งานดูตัวอย่างโค๊ดด้านล่างได้เลย
import cv2
import numpy as np
img = cv2.imread('somethingElse.jpg',0)
rows,cols = img.shape

M = cv2.getRetationMatrix2D((cols/2,rows/2),90,1)
dst = cv2.warpAffine(img,M,(cols,rows))


การแปลงรูปแบบเลียนแบบ Affine Transformation

  • ในการเปลี่ยนแปลงเลียนแบบเส้นคู่ขนาน ภาพเดิมจะยังคงเป็นคู่ขนาน เพื่อหาเมทริกซ์การเปลี่ยนแปลงที่เราต้องมีสามจุด จากภาพที่นำเข้ามา และตำแหน่งที่สอดคล้องกันของภาพผลลัพธ์ ดังนั้น cv2.getAffineTransform จะสร้างตารางเมทริกซ์ขนาด 2x3 ซึ่งจะถูกส่งผ่านไปยังคำสั่ง cv2.warpAffine
  • สามารถทดลองทำได้โดย Code ด้านล่างนี้
import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('songthingElse.png')
rows,cols,ch = img.shape
pts1 = np.float32([[50,50],[200,50],[50,200]])
pts2 = np.float32([[10,100],[200,50],[100,250]])

M = cv2.getAffineTransform(pts1,pts2)

dst = cv2.warpAffine(img,M,(cols,rows))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()

การเปลี่ยนมุม Perspective Transformation

  • สำหรับการเปลี่ยนแปลงมุมมอง จำเป็นต้องมีการเปลี่ยนแปลงขนาดตารางเมทริกซ์ 3x3 โดยเส้นตรงจะยังคงอยู่ที่เดิม แม้จะเปลี่ยนแปลงแล้ว เพื่อหาเมทริกซ์การเปลี่ยนแปลงครั้งนี้คุณจำเป็นจะต้องมี 4 จุดสำหรับภาพที่นำเข้ามา โดยหาจุดที่สอดคล้องกัน ในภาพผลลัพธ์ การเปลี่ยนแปลงเมทริกซ์สามารถใช้คำสั่ง cv2.getPerspectiveTransform และจากนั้นให้ใช้ cv2.warpPerspective กับ 3x3 เมทริกซ์การเปลี่ยนแปลงนี้
  • โค๊ดตัวอย่างสำหรับ Perspective Transformation
import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('sudokusmall.png')
rows,cols,ch = img.shape

pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])

M = cv2.getPerspectiveTransform(pts1,pts2)

dst = cv2.warpPerspective(img,M,(300,300))

plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()