- 1. การใช้งาน Bitwise และการกำบัง
- 2. Convolution & Blurring
- 3. Sharpening - การกลับภาพเบลอ
- 4. การนวดข้าว (Binarization)
- 5. การขยายตัวการกัดเซาะการเปิด / การปิด
- 6. การตรวจจับขอบและการไล่ระดับสีของภาพ
- 14. Perspective & Affine Transform
- 8. แอปพลิเคชัน Live Sketch
ในบทช่วยสอนก่อนหน้านี้เราได้เรียนรู้เกี่ยวกับ OpenCV และทำการประมวลผลภาพขั้นพื้นฐานแล้วในบทช่วยสอนถัดไปเราได้ทำการปรับแต่งรูปภาพใน OpenCV เช่นการครอบตัดการหมุนการแปลงรูปภาพเป็นต้นดังนั้นเราจึงได้เรียนรู้เกี่ยวกับการจัดการรูปภาพก่อนหน้า เทคนิคการจัดการภาพมากขึ้นชอบและในตอนท้ายของการกวดวิชาที่เราจะสร้างโปรแกรมหลาม OpenCV ที่จะทำให้ร่างสดจากอาหารสดเว็บแคม แอปพลิเคชั่นนี้จะใช้ฟังก์ชั่นการประมวลผลภาพมากมายที่เราได้เรียนรู้ไปแล้วหรือจะเรียนรู้ในบทช่วยสอนนี้ดังนั้นนี่จะเป็นตัวอย่างที่ใช้ได้จริงในการครอบคลุมฟังก์ชันทั้งหมด
ตามที่บอกไว้ในบทช่วยสอนก่อนหน้านี้ OpenCV คือ Open Source Commuter Vision Library ซึ่งมีอินเตอร์เฟส C ++, Python และ Java และรองรับ Windows, Linux, Mac OS, iOS และ Android ดังนั้นจึงสามารถติดตั้งได้อย่างง่ายดายใน Raspberry Pi ด้วยสภาพแวดล้อม Python และ Linux และ Raspberry Pi พร้อม OpenCV และกล้องที่ติดมาสามารถใช้เพื่อสร้างแอปพลิเคชันการประมวลผลภาพแบบเรียลไทม์มากมายเช่นการตรวจจับใบหน้าการล็อกใบหน้าการติดตามวัตถุการตรวจจับป้ายทะเบียนรถยนต์ระบบรักษาความปลอดภัยภายในบ้าน
ในการกวดวิชานี้เราจะได้เห็นมากขึ้นบางกิจวัตรภาพโดยใช้ Python OpenCV ที่นี่เราจะเรียนรู้การใช้ฟังก์ชันต่อไปนี้กับรูปภาพโดยใช้ Python OpenCV:
- การดำเนินการ Bitwise และการกำบัง
- Convolution & Blurring
- Sharpening - การกลับภาพเบลอ
- เกณฑ์ (Binarization)
- การขยายตัวการกัดเซาะการเปิด / การปิด
- การตรวจจับขอบและการไล่ระดับสีของภาพ
- Perspective & Affine Transform
- แอปพลิเคชัน Live Sketch
1. การใช้งาน Bitwise และการกำบัง
การใช้งาน Bitwise ช่วยคุณในการมาสก์ภาพและช่วยให้คุณสร้างภาพง่ายๆ
ทำสี่เหลี่ยม
import cv2 import numpy เป็น np # เราใช้แค่สองมิติเพราะนี่คือภาพระดับสีเทาถ้าเราใช้ #colored image เราก็ใช้ rectangle = np.zeros ((300,300,3), np.uint8) # การสร้างตาราง สี่เหลี่ยม = np.zeros ((300,300), np.uint8) cv2.rectangle (square, (50,50), (250,250), 255, -1) cv2.imshow ("square", square) cv2. WaitKey (0)
การสร้างวงรี
ellipse = np.zeros ((300,300), np.uint8) cv2.ellipse (วงรี, (150,150), (150,150), 30,0,180,255, -1) cv2.imshow ("วงรี", วงรี) cv2.waitKwait (0)
การทดลองกับการดำเนินการระดับบิต
#AND_s แสดงเฉพาะจุดที่ทั้งสองตัดกัน
BitwiseAND = cv2.bitwise_and (สี่เหลี่ยมวงรี) cv2.imshow ("AND", BitwiseAND) cv2.waitKey (0)
#OR_s แสดงเฉพาะที่สี่เหลี่ยมจัตุรัสหรือวงรี
BitwiseOR = cv2.bitwise_or (สี่เหลี่ยมวงรี) cv2.imshow ("OR", BitwiseOR) cv2.waitKey (0)
#XOR_s แสดงเฉพาะที่ที่มีอยู่ด้วยตัวเอง
BitwiseXOR = cv2.bitwise_xor (สี่เหลี่ยมวงรี) cv2.imshow ("XOR", BitwiseXOR) cv2.waitKey (0)
#NOT_s แสดงทุกสิ่งที่ไม่ได้เป็นส่วนหนึ่งของวงรีและ การดำเนินการ NOT สามารถใช้ได้กับรูปเดียวเท่านั้น
BitwiseNOT_elp = cv2.bitwise_not (วงรี) cv2.imshow ("NOT_ellipse", BitwiseNOT_elp) cv2.waitKey (0) cv2.destroyAllWindows ()
2. Convolution & Blurring
บิดอยู่ในการดำเนินการทางคณิตศาสตร์ที่ดำเนินการในสองฟังก์ชั่นการผลิตที่ฟังก์ชั่นที่สามซึ่งโดยปกติจะเป็นรุ่นที่ปรับเปลี่ยนฟังก์ชั่นเดิม
ภาพที่ส่งออก = รูปภาพฟังก์ชันขนาดเคอร์เนล
ในการมองเห็นด้วยคอมพิวเตอร์เราใช้เคอร์เนลเพื่อระบุขนาดที่เราเรียกใช้ฟังก์ชันการปรับแต่งภาพของเรา
การเบลอคือการดำเนินการที่เราเฉลี่ยพิกเซลภายในพื้นที่ (เคอร์เนล)
OpenCV ทำให้ภาพเบลอโดยใช้เมล็ดเคอร์เนลจะบอกวิธีเปลี่ยนค่าของพิกเซลที่กำหนดโดยการรวมกับพิกเซลที่อยู่ใกล้เคียงจำนวนต่างๆเคอร์เนลจะถูกนำไปใช้กับทุกพิกเซลในภาพทีละภาพเพื่อสร้างภาพสุดท้าย
พูดง่ายๆก็คือการแปลงภาพเป็นเพียงองค์ประกอบที่ชาญฉลาดของการคูณสองเมทริกซ์ตามด้วยผลรวม
เราสามารถเข้าใจได้จากตัวอย่างต่อไปนี้
ข้างต้นคือเคอร์เนล 3X3
เราคูณด้วย 1/25 เพื่อทำให้ปกติคือผลรวมเป็น 1 เราได้เพิ่มความเข้มหรือลดความเข้มเช่นเดียวกับในกรณีของการทำให้ภาพสว่างขึ้นหรือมืดลง
มาทดสอบวิธีการทำให้เบลอ opencv filter2Dโดยใช้ฟังก์ชัน cv2.filter2D (image, -1, kernel)
import cv2 import numpy เป็น np image = cv2.imread ('elephant.jpg') cv2.imshow ('original', image) cv2.waitKey (0)
# การสร้างเมทริกซ์เคอร์เนล 3x3
kernel_3x3 = np.ones ((3,3), np.float32) / 9
# เราใช้ cv2.filter2D เพื่อแปลงเคอร์เนลด้วยรูปภาพ
เบลอ = cv2.filter2D (รูปภาพ -1, kernel_3x3) cv2.imshow ('3x3_blurring', เบลอ) cv2.waitKey (0)
# การสร้างเมทริกซ์เคอร์เนล 7x7
kernel_7x7 = np.ones ((7,7), np.float32) / 49
# เราใช้ cv2.filter2D เพื่อแปลงเคอร์เนลด้วยรูปภาพ
เบลอ = cv2.filter2D (รูปภาพ -1, kernel_7x7) cv2.imshow ('7x7_blurring', เบลอ) cv2.waitKey (0) cv2.destroyAllWindows ()
มีวิธีการเบลออื่น ๆด้วยเช่นกัน:
cv2.blur -ค่าเฉลี่ยในหน้าต่างที่ระบุ
cv2 GaussianBlur -คล้ายกัน แต่ใช้หน้าต่าง Gaussian (เน้นจุดรอบ ๆ ตรงกลางมากกว่า)
cv2.medianBlur -ใช้ค่ามัธยฐานขององค์ประกอบทั้งหมดในหน้าต่าง
cv2.bilateralFilter– Blurs ในขณะที่รักษาขอบให้คม แต่จะรักษาขอบและรายละเอียดของเส้น
เราจะเห็นทีละภาพด้านล่างก่อนอื่นให้แสดงภาพต้นฉบับโดยใช้รหัสด้านล่าง:
import cv2 import numpy เป็น np image = cv2.imread ('elephant.jpg') cv2.imshow ('original', image) cv2.waitKey (0)
cv2.blur:
ในวิธีนี้การหาค่าเฉลี่ยทำได้โดยการปรับภาพด้วยฟิลเตอร์กล่องแบบปกติซึ่งจะเกิดขึ้นใต้กล่องและแทนที่องค์ประกอบกลาง นี่ขนาดของกล่องจะต้องแปลกและบวก
# cv2.blur เบลอ = cv2.blur (ภาพ, (3,3)) cv2.imshow ('เฉลี่ย', เบลอ) cv2.waitKey (0)
cv2 GaussianBlur:
# cv2 GaussianBlur # แทน ตัวกรองกล่องลองเคอร์เนล Gaussian Gaussian = cv2 GaussianBlur (รูปภาพ (7,7) 0) cv2.imshow ('Gaussian เบลอ', Gaussian) cv2.waitKey (0)
cv2.medianBlur:
ใช้ค่ามัธยฐานของพิกเซลทั้งหมดภายใต้พื้นที่เคอร์เนลและองค์ประกอบกลางจะถูกแทนที่ด้วยค่ามัธยฐานนี้
# cv2.medianBlur # ใช้ ค่ามัธยฐานของพิกเซลทั้งหมดภายใต้พื้นที่เคอร์เนลและองค์ประกอบกลาง # ถูกแทนที่ด้วยค่ามัธยฐานนี้ เฉลี่ย = cv2.medianBlur (ภาพที่ 5) cv2.imshow ('แบ่งการเบลอ' มัธยฐาน) cv2.waitKey (0)
cv2.bilateralFilter:
ทวิภาคีมีประสิทธิภาพในการขจัดเสียงรบกวนในขณะที่รักษาขอบให้คม
# cv2.bilateralFilter #Bilateral มีประสิทธิภาพมากในการกำจัดสัญญาณรบกวนในขณะที่รักษาขอบให้คม ทวิภาคี = cv2.bilateralFilter (image, 9,75,75) cv2.imshow ('ทวิภาคีเบลอ', ทวิภาคี) cv2.waitKey (0) cv2 ทำลาย AllWindows ()
Image De-noising-non Local หมายถึง Denoising
import cv2 import numpy เป็น np image = cv2.imread ('elephant.jpg') cv2.imshow ('original', image) cv2.waitKey (0)
#parameter หลังจากที่ไม่เป็นความแข็งแรงของตัวกรอง 'H' (5-10 เป็นช่วงที่ดี) #next เป็นชั่วโมงสำหรับส่วนประกอบของสีตั้งเป็นเดียวกันค่าเป็นชั่วโมงอีกครั้ง
dst = cv2.fastNlMeansDenoisingColored (รูปภาพ, ไม่มี, 6,6,7,21) cv2.imshow ('Fast หมายถึง denois', dst) cv2.waitKey (0) cv2.destroyAllWindows ()
วิธีการที่ไม่ใช่เฉพาะท้องถิ่นมี 4 รูปแบบ
cv2.fastNlMeansDenoising () - สำหรับภาพระดับสีเทาเดียว
cv2.fastNlMeansDenoisingColored () - ภาพสีเดียว
cv2.fastNlmeansDenoisingMulti () - สำหรับลำดับภาพสีเทา
cv2.fastNlmeansDenoisingcoloredMulti () - สำหรับลำดับภาพที่มีสี
3. Sharpening - การกลับภาพเบลอ
การเหลาเป็นสิ่งที่ตรงกันข้ามกับการเบลอจุดแข็งหรือเน้นที่ขอบในภาพ
เคอร์เนล =,,
เมทริกซ์เคอร์เนลของเรารวมได้ถึงหนึ่งดังนั้นจึงไม่จำเป็นต้องทำให้เป็นมาตรฐาน (เช่นคูณด้วยปัจจัยเพื่อให้มีความสว่างเท่ากับของต้นฉบับ) หากเคอร์เนลไม่ได้ถูกทำให้เป็นมาตรฐานเป็น 1 ภาพจะสว่างขึ้นหรือมืดลง
import cv2 import numpy เป็น np image = cv2.imread ('elephant.jpg') cv2.imshow ('original', image) cv2.waitKey (0)
kernel_sharpening = np.array (,
])
# การใช้เคอร์เนลเหลาเพื่อป้อนรูปภาพ
sharpened = cv2.filter2D (image, -1, kernel_sharpening) cv2.imshow ('sharpened image', sharpened) cv2.waitKey (0) cv2.destroyAllWindows ()
4. การนวดข้าว (Binarization)
Thresholding คือการแปลงรูปภาพเป็นรูปแบบไบนารี ใน opencv มีฟังก์ชั่นแยกต่างหากสำหรับ thresholding ที่กำหนดเป็น
Cv2.threshold (รูปภาพ, ค่าขีด จำกัด, ค่าสูงสุด, ประเภทเกณฑ์)
ประเภทเกณฑ์ดังต่อไปนี้:
- cv2.THRESH_BINARY - ที่พบบ่อยที่สุด
- cv2 THRESH_BINARY_INV - พบบ่อยที่สุด
- cv2.THRESH_TRUNC
- cv2.THRESH_TOZERO
- cv2 THRESH_TOZERO_INV
หมายเหตุ: จำเป็นต้องแปลงรูปภาพเป็นโทนสีเทาก่อนถึงขีด จำกัด
import cv2 import numpy เป็น np #load image เป็น grayscale image = cv2.imread ('gradient.jpg', 0) cv2.imshow ('original', image) cv2.waitKey (0)
# ค่าต่ำกว่า 127 ไปที่ 0 (สีดำ) และสูงกว่า 127 ไปที่ 255 (สีขาว)
_, thresh1 = cv2.threshold (รูปภาพ, 127,255, cv2.THRESH_BINARY) cv2.imshow ('1 threshold', thresh1) cv2.waitKey (0)
#value ต่ำกว่า 127 ไปที่ 255 และค่าที่สูงกว่า 127 ไปที่ 0 (กลับด้านบน)
_, thresh2 = cv2.threshold (รูปภาพ, 127,255, cv2.THRESH_BINARY_INV) cv2.imshow ('2 threshold', thresh2) cv2.waitKey (0)
#value ที่สูงกว่า 127 จะถูกตัดทอน (ถือไว้) ที่ 127 อาร์กิวเมนต์ 255 ไม่ได้ใช้
_, thresh3 = cv2.threshold (รูปภาพ, 127,255, cv2.THRESH_TRUNC) cv2.imshow ('3 thresh trunc', thresh3) cv2.waitKey (0)
# ค่าต่ำกว่า 127 ไปที่ 0 ส่วนสูงกว่า 127 จะไม่เปลี่ยนแปลง
_, thresh4 = cv2.threshold (รูปภาพ, 127,255, cv2.THRESH_TOZERO) cv2.imshow ('4 threshold', thresh4) cv2.waitKey (0)
#Revesrse จากด้านบนด้านล่าง 127 จะไม่เปลี่ยนแปลงส่วนที่สูงกว่า 127 จะเป็นศูนย์
_, thresh5 = cv2.threshold (รูปภาพ 127,255, cv2.THRESH_TOZERO_INV) cv2.imshow ('5 threshold', thresh5) cv2.waitKey (0) cv2.destroyAllWindows ()
5. การขยายตัวการกัดเซาะการเปิด / การปิด
นี่คือการดำเนินการในด้านสัณฐานวิทยาทางคณิตศาสตร์
การขยาย - เพิ่มพิกเซลให้กับขอบเขตของวัตถุในภาพ
การพังทลาย - ลบพิกเซลที่ขอบเขตของวัตถุในภาพ
การเปิด - การกร่อนตามด้วยการขยาย
การปิด - การขยายตัวตามด้วยการกัดเซาะ
การเปิดมีประโยชน์อย่างมากในการทำให้ภาพชัดขึ้นเนื่องจากก่อนอื่นจะทำให้ภาพบางลงโดยการกัดเซาะ (ลบสัญญาณรบกวน) แล้วจึงขยายออก
ความสับสนกับการขยายและการสึกกร่อน
บางครั้งมีความสับสนระหว่างการขยายและการสึกกร่อนโดยปกติในภาพที่มีพื้นหลังสีขาวเนื่องจาก opencv พิจารณาว่าพื้นหลังสีขาวเป็นภาพที่ขยายหรือสึกกร่อนแทนภาพต้นฉบับดังนั้นในกรณีนี้การสึกกร่อนจะทำงานในลักษณะการขยายและในทางกลับกันดังที่แสดงในตัวอย่างภาพ แสดงด้านล่าง.
อย่าลืมว่า Dilationจะเพิ่มพิกเซลให้กับขอบเขตของวัตถุในภาพในขณะที่Erosionลบพิกเซลที่ขอบเขตของวัตถุในภาพ
import cv2 import numpy เป็น np image = cv2.imread ('imagecv.png', 0) cv2.imshow ('original', image) cv2.waitKey (0)
#Erosion
# มากำหนดขนาดเคอร์เนลของเรากัน
เคอร์เนล = np.ones ((5,5), np.uint8)
# ตอนนี้เราลบภาพการทำซ้ำนี่ไม่ใช่ครั้งที่คุณต้องการที่จะกัดเซาะภาพ
erosion = cv2.erode (รูปภาพ, เคอร์เนล, การวนซ้ำ = 1) cv2.imshow ('การพังทลาย', การกัดเซาะ) cv2.waitKey (0)
# การขยาย
การขยาย = cv2.dilate (รูปภาพ, เคอร์เนล, การวนซ้ำ = 1) cv2.imshow ('การขยาย', การขยาย) cv2.waitKey (0)
# เปิดดีสำหรับการลบเสียงรบกวน
opening = cv2.morphologyEx (รูปภาพ, cv2.MORPH_OPEN, เคอร์เนล) cv2.imshow ('opening', opening) cv2.waitKey (0)
# ปิดดีสำหรับการลบเสียงรบกวน
ปิด = cv2.morphologyEx (รูปภาพ, cv2.MORPH_CLOSE, เคอร์เนล) cv2.imshow ('ปิด', ปิด) cv2.waitKey (0) cv2.destroyAllWindows ()
6. การตรวจจับขอบและการไล่ระดับสีของภาพ
การตรวจจับขอบเป็นส่วนที่สำคัญมากในการมองเห็นของคอมพิวเตอร์โดยเฉพาะอย่างยิ่งเมื่อต้องจัดการกับรูปทรง
ขอบสามารถกำหนดเป็นขอบเขตของภาพได้จริง ๆ แล้วพวกมันเป็นขอบที่กำหนดวัตถุในภาพซึ่งเก็บข้อมูลจำนวนมากเกี่ยวกับภาพไว้
ขอบอย่างเป็นทางการสามารถกำหนดได้ว่าเป็นการเปลี่ยนแปลงอย่างกะทันหัน (ความไม่ต่อเนื่อง) ในภาพและสามารถเข้ารหัสข้อมูลได้มากถึงพิกเซล
ภาพด้านบนแสดงให้เห็นว่าการมองเห็นของคอมพิวเตอร์ระบุและจดจำภาพได้อย่างไร
อัลกอริธึมการตรวจจับขอบ: - อัลกอริทึมการตรวจจับขอบมีสามประเภทหลัก ๆ
- Sobel -เพื่อเน้นภาพแนวตั้งหรือแนวนอน
- Laplacian -เหมาะสมที่สุดเนื่องจากอัตราความผิดพลาดต่ำขอบที่กำหนดไว้อย่างดีและการตรวจจับที่แม่นยำ
- อัลกอริทึมการตรวจจับ Canny Edge (พัฒนาโดย john.F.Canny ในปี 1986)
1. ใช้ Gaussian เบลอ
2. ค้นหาการไล่ระดับสีเข้มของภาพ
3. ใช้การปราบปรามที่ไม่สูงสุด (เช่นลบพิกเซลที่ไม่ใช่ขอบ)
4. Hysteresis ใช้เกณฑ์ (เช่นถ้าพิกเซลอยู่ในเกณฑ์ด้านบนและด้านล่างจะถือว่าเป็นขอบ)
import cv2 import numpy เป็น np image = cv2.imread ('input.jpg', 0) height, width = image.shape
#sobel
# แยกขอบ sobel
sobel_x = cv2.Sobel (image, cv2.CV_64F, 0,1, ksize = 5) sobel_y = cv2.Sobel (image, cv2.CV_64F, 1,0, ksize = 5) cv2.imshow ('original', image) cv2.waitKey (0) cv2.imshow ('sobelx', sobel_x) cv2.waitKey (0)
# ธรรมดา
cv2.imshow ('sobely', sobel_y) cv2.waitKey (0)
sobel_OR = cv2.bitwise_or (sobel_x, sobel_y) cv2.imshow ('sobelOR', sobel_OR) cv2.waitKey (0)
#laplaian
laplacian = cv2.Laplacian (รูปภาพ, cv2.CV_64F) cv2.imshow ('Laplacian', laplacian) cv2.waitKey (0)
อัลกอริธึมการตรวจจับขอบ #canny ใช้ค่าการไล่ระดับสีเป็นเกณฑ์ #in canny
เราต้องระบุค่าสองค่า: threshold1 และ threshold2
# การไล่ระดับสีใด ๆ ที่ใหญ่กว่าเกณฑ์ 2 ถือเป็นขอบ
# การไล่ระดับสีใด ๆ ที่ใหญ่กว่าเกณฑ์ 1 จะถือว่าไม่เป็นขอบ
# ค่าที่อยู่ระหว่าง threshold 1 และ threshold 2 เป็นทั้ง edge หรือ non-edge
# ในการเชื่อมต่อของความเข้มในกรณีนี้ค่าใด ๆ ที่ต่ำกว่า 60 จะถือเป็น
#non edge เมื่อค่าใด ๆ ที่สูงกว่า 120 จะถือเป็นขอบ
canny = cv2.Canny (รูปภาพ 60,120) cv2.imshow ('canny', canny ) cv2.waitKey (0) cv2.destroyAllWindows ()
14. Perspective & Affine Transform
ลองย้อนกลับไปดูการแปลงแบบ Affine และ non-affine กันดีกว่าภาพต้นฉบับที่แสดงด้านล่างเป็นภาพที่ไม่เกี่ยวกับความสัมพันธ์เนื่องจากขอบจะบรรจบกันในบางจุดอย่างไรก็ตามเราสามารถทำให้ตรงได้โดยการแปรปรวนและรับมุมมอง แปลง.
สำหรับการแปลงมุมมองนี้เราต้องการพิกัดสี่จุดของภาพต้นฉบับจากนั้นจุดสี่จุดของภาพที่ส่งออกจะแสดงด้วย point_A และ point_B ประการแรกด้วยความช่วยเหลือของจุดเหล่านี้เราคำนวณเมทริกซ์การเปลี่ยนแปลง M ด้วยความช่วยเหลือของ ฟังก์ชัน getPerspectiveTransform
จากนั้นเมทริกซ์นี้จะถูกกำหนดให้กับฟังก์ชัน warpPerspective เพื่อสร้างผลลัพธ์สุดท้าย
ตอนนี้เรามาลองการแปลงมุมมองกันก่อน
import cv2 import numpy เป็น np import matplotlib.pyplot เป็น plt image = cv2.imread ('paper.jpg') cv2.imshow ('original', image) cv2.waitKey (0)
# ประสาน 4 มุมของภาพต้นฉบับ
point_A = np.float32 (,,,])
# พิกัดของ 4 มุมของผลลัพธ์ที่ต้องการ
# เราใช้อัตราส่วนของกระดาษ A4 1: 1.41
point_B = np.float32 (,,,])
# ใช้สองชุดของจุดสองจุดเพื่อคำนวณเมทริกซ์การแปลงมุมมองM
M = cv2.getPerspectiveTransform (points_A, points_B) warped = cv2.warpPerspective (image, M, (420,594)) cv2.imshow ('warpprespective', warped ) cv2.waitKey (0) cv2.destroyAllWindows ()
Affine transform นั้นง่ายกว่าการแปลงแบบ non-affine เนื่องจากเราต้องการเพียงสามคะแนนเพื่อรับการแปลงร่าง กระบวนการทั้งหมดจะเหมือนกัน แต่แทนที่จะเป็นการแปลงมุมมองตอนนี้เรามีการแปลงเหมือนกันและเรากำหนด cols และแถวใน warpAffine จากฟังก์ชันรูปร่างแทนที่จะป้อนด้วยตนเอง
import cv2 import numpy เป็น np import matplotlib.pyplot เป็น plt image = cv2.imread ('box.jpg') แถว, cols = image.shape cv2.imshow ('original', image) cv2.waitKey (0)
# ประสาน 3 มุมของภาพต้นฉบับ
point_A = np.float32 (,,])
# พิกัดของ 3 มุมของผลลัพธ์ที่ต้องการ
# เราใช้อัตราส่วนของกระดาษ A4 1: 1.41
point_B = np.float32 (,,])
# ใช้สองชุดสองจุดเพื่อคำนวณเมทริกซ์ # การแปลงข้อมูล Affine
, M
M = cv2.getAffineTransform (points_A, points_B) warped = cv2.warpAffine (image, M, (cols, row )) cv2.imshow ('warpaffine', warped ) cv2.waitKey (0) cv2.destroyAllWindows ()
8. แอปพลิเคชัน Live Sketch
ก่อนอื่นขอแสดงความยินดีกับตัวเองที่คุณได้ทำมินิโปรเจ็กต์นี้หลังจากอ่านฟังก์ชั่นการปรับแต่งรูปภาพทั้งหมดด้านบน ดังนั้นในโปรเจ็กต์ขนาดเล็กของ Python OpenCVเราจะได้เรียนรู้แนวคิดใหม่ของลูปและฟังก์ชัน หากคุณคุ้นเคยกับการเขียนโปรแกรมคุณต้องมีความคิดที่กว้างขึ้นว่าฟังก์ชันและลูปคืออะไร อย่างไรก็ตามใน python แนวคิดพื้นฐานของลูปและฟังก์ชันยังคงเหมือนเดิม แต่วิธีการกำหนดจะเปลี่ยนไปเล็กน้อย
ดังนั้นในตอนเริ่มต้นของโปรแกรมนี้เราจะเห็นกลุ่มของข้อความที่อยู่ภายใต้ " ร่าง def (รูปภาพ): " นี่คือคำจำกัดความที่เป็นทางการของฟังก์ชันกลุ่มหนึ่งของข้อความที่ทำงานร่วมกัน
ดังนั้นร่างนี้จึงเป็นฟังก์ชันในฟังก์ชัน python ถูกกำหนดโดย "def" และลงท้ายด้วยเครื่องหมาย ":" นอกจากนี้คำสั่งที่จำเป็นต้องอยู่ในฟังก์ชันหรือคุณสามารถพูดได้ว่าสิ่งใดที่จำเป็นเพื่อให้ฟังก์ชันทำงานได้อย่างถูกต้องได้รับการจัดแนวด้านข้างโดยอัตโนมัติโดยฟังก์ชัน ดังนั้นเพื่อให้ออกมาจากฟังก์ชั่นข้อความที่จำเป็นต้องจัดชิดซ้ายทั้งหมด สำหรับข้อมูลอ้างอิงเพิ่มเติมคุณสามารถอ้างถึง Google เกี่ยวกับวิธีการกำหนดฟังก์ชันใน python
ดังนั้นในฟังก์ชันร่างนี้เราจึงได้นำเสนอการประมวลผลภาพหลายชั้นซึ่งรวมเข้าด้วยกันเพื่อให้ได้ผลลัพธ์ประการแรกภาพจะถูกแปลงเป็นโทนสีเทาเพื่อให้ opencv สามารถประมวลผลได้อย่างง่ายดายจากนั้นจึงใช้ภาพเบลอแบบเกาส์เซียนกับภาพระดับสีเทาเพื่อลดสัญญาณรบกวน จากนั้นขอบจะถูกดึงออกด้วยความช่วยเหลือของอัลกอริธึมการตรวจจับขอบของ canny จากนั้นจะใช้ไบนารีผกผันกับภาพที่กำหนดขอบที่นี่การผกผันไบนารีสามารถทำได้โดย bitwise_NOT แต่เราได้เลือกโดยเจตนาไบนารีผกผันเกณฑ์นี้เนื่องจากให้อิสระ เพื่อตั้งค่าพารามิเตอร์จนกว่าเราจะได้ภาพที่ชัดเจน
นอกจากนี้ยังจะต้องทราบว่าฟังก์ชั่นใช้เวลาภาพการขัดแย้งและผลตอบแทนที่ทั้งสองมีปากเสียง ret และหน้ากากในขณะที่ ret คือบูลีนบอกว่าฟังก์ชันทำงานสำเร็จหรือไม่และมาสก์คือผลลัพธ์สุดท้ายของฟังก์ชันนั่นคือรูปภาพที่ประมวลผล
จากนั้นแนวคิดที่สองคือการใช้งานเว็บแคมใน opencvที่ทำโดย cv2.VideoCapture (0) ฟังก์ชั่นซึ่งเก็บภาพไว้ใน ฝาปิด วัตถุที่สามารถอ่านฝาปิดได้ด้วย ฟังก์ชัน cap.read () และที่นี่เพื่อสังเกต ฝาปิดนั้น read () อยู่ ภายในวงไม่มีที่สิ้นสุด ในขณะที่วนซ้ำ เนื่องจากต้องจับภาพอย่างต่อเนื่องเพื่อให้รู้สึกถึงวิดีโอสดโดยที่อัตราเฟรมของวิดีโอจะเป็นอัตราเฟรมของเว็บแคมซึ่งส่วนใหญ่อยู่ระหว่าง 24 ถึง 60 fps
cap.read () ส่งคืน ret และ frameโดยที่ ret เป็นบูลีนที่แสดงว่าฟังก์ชันทำงานสำเร็จหรือไม่และเฟรมมีภาพที่ถ่ายโดยเว็บแคม
ด้านล่างนี้คือโค้ด Python OpenCV ที่สมบูรณ์สำหรับเรียกใช้ Live Sketch
import cv2 import numpy เป็น np #sketch สร้างฟังก์ชั่น def sketch (image): #convert image to greyscale img_gray = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) # ทำความสะอาดภาพโดยใช้ Gaussian เบลอ img_gray_blur = cv2 5,5), 0) #extract edge canny_edges = cv2.Canny (img_gray_blur, 10,70) # do an invert binarize the image ret, mask = cv2.reshold (canny_edges, 70,255, cv2.THRESH_BINARY_INV) return mask #initialize เว็บแคม, หมวกเป็นวัตถุที่มีให้โดยวิดีโอจับภาพ #it มีแบบบูลแสดงให้เห็นว่ามันเป็นที่ประสบความสำเร็จ (เกษียณ) #it ยังมีภาพที่รวบรวมจากเว็บแคม (เฟรม) cap = cv2.VideoCapture (0) ในขณะที่ True: ret, frame = cap.read () cv2.imshow ('livesketcher', ร่าง (เฟรม)) หาก cv2.waitKey (1) == 13: # 13 คือตัว แบ่ง enterkey #release กล้องและปิดหน้าต่างอย่าลืมปล่อยเว็บแคมโดยใช้ cap.release () cap.release () cv2.destroyAllWindows ()
นี่คือจุดสิ้นสุดของส่วนที่ 2 ของการปรับแต่งรูปภาพใน Python-OpenCV เพื่อให้เข้าใจถึงวิสัยทัศน์ของคอมพิวเตอร์และ OpenCV ได้ดีให้อ่านบทความก่อนหน้านี้ (เริ่มต้นใช้งาน Python OpenCV และ Image Manipulations ใน Python OpenCV (ตอนที่ 1) และคุณจะสามารถสร้างสิ่งที่ยอดเยี่ยมด้วย Computer Vision