ฉันจะทำให้ภาพคมชัดขึ้นโดยใช้OpenCV ได้อย่างไร
มีหลายวิธีในการทำให้เรียบหรือเบลอ แต่ไม่มีเลยที่ฉันจะเห็นการเหลา
ฉันจะทำให้ภาพคมชัดขึ้นโดยใช้OpenCV ได้อย่างไร
มีหลายวิธีในการทำให้เรียบหรือเบลอ แต่ไม่มีเลยที่ฉันจะเห็นการเหลา
คำตอบ:
มีขั้นตอนทั่วไปอย่างหนึ่งในบทความ Wikipedia เกี่ยวกับการกำบังที่ไม่คมชัด :
คุณใช้ตัวกรองการปรับให้เรียบแบบเกาส์เซียนและลบเวอร์ชันที่ปรับให้เรียบออกจากรูปภาพต้นฉบับ (ด้วยวิธีการถ่วงน้ำหนักเพื่อให้ค่าของพื้นที่คงที่คงที่)
ที่จะได้รับรุ่นรุนแรงขึ้นของการframe
เข้าสู่image
: (ทั้งcv::Mat
)
cv::GaussianBlur(frame, image, cv::Size(0, 0), 3);
cv::addWeighted(frame, 1.5, image, -0.5, 0, image);
พารามิเตอร์มีบางอย่างที่คุณต้องปรับด้วยตัวคุณเอง
นอกจากนี้ยังมีการเหลา Laplacian คุณควรหาอะไรบางอย่างเมื่อคุณใช้ Google
คุณสามารถลองใช้เคอร์เนลธรรมดาและฟังก์ชันfilter2Dเช่นใน Python:
kernel = np.array([[-1,-1,-1], [-1,9,-1], [-1,-1,-1]])
im = cv2.filter2D(im, -1, kernel)
Wikipedia มีภาพรวมที่ดีของเมล็ดพร้อมตัวอย่างเพิ่มเติมที่นี่ - https://en.wikipedia.org/wiki/Kernel_(image_processing)
ในการประมวลผลภาพเคอร์เนลเมทริกซ์คอนโวลูชั่นหรือมาสก์เป็นเมทริกซ์ขนาดเล็ก ใช้สำหรับการเบลอการเหลาการทำให้นูนการตรวจจับขอบและอื่น ๆ สิ่งนี้ทำได้โดยทำการ Convolution ระหว่างเคอร์เนลและรูปภาพ
คุณสามารถค้นหาโค้ดตัวอย่างเกี่ยวกับความคมชัดของภาพโดยใช้ "หน้ากากไม่ชัด" อัลกอริทึมที่OpenCV เอกสาร
การเปลี่ยนค่านิยมของsigma
, threshold
, amount
จะให้ผลลัพธ์ที่แตกต่างกัน
// sharpen image using "unsharp mask" algorithm
Mat blurred; double sigma = 1, threshold = 5, amount = 1;
GaussianBlur(img, blurred, Size(), sigma, sigma);
Mat lowContrastMask = abs(img - blurred) < threshold;
Mat sharpened = img*(1+amount) + blurred*(-amount);
img.copyTo(sharpened, lowContrastMask);
คุณสามารถทำให้ภาพคมชัดขึ้นโดยใช้มาสก์ที่ไม่คมชัด คุณสามารถค้นหาข้อมูลเพิ่มเติมเกี่ยวกับการกำบังไม่ชัดนี่ และนี่คือการใช้งาน Python โดยใช้ OpenCV:
import cv2 as cv
import numpy as np
def unsharp_mask(image, kernel_size=(5, 5), sigma=1.0, amount=1.0, threshold=0):
"""Return a sharpened version of the image, using an unsharp mask."""
blurred = cv.GaussianBlur(image, kernel_size, sigma)
sharpened = float(amount + 1) * image - float(amount) * blurred
sharpened = np.maximum(sharpened, np.zeros(sharpened.shape))
sharpened = np.minimum(sharpened, 255 * np.ones(sharpened.shape))
sharpened = sharpened.round().astype(np.uint8)
if threshold > 0:
low_contrast_mask = np.absolute(image - blurred) < threshold
np.copyto(sharpened, image, where=low_contrast_mask)
return sharpened
def example():
image = cv.imread('my-image.jpg')
sharpened_image = unsharp_mask(image)
cv.imwrite('my-sharpened-image.jpg', sharpened_image)
amount
เป็นเพียงปริมาณของการเหลา ตัวอย่างเช่นamount
2.0 จะให้ภาพที่คมชัดกว่าเมื่อเทียบกับค่าเริ่มต้นคือ 1.0 threshold
เป็นเกณฑ์สำหรับมาสก์คอนทราสต์ต่ำ กล่าวอีกนัยหนึ่งพิกเซลที่ความแตกต่างระหว่างอินพุตและภาพเบลอน้อยกว่าthreshold
จะยังคงไม่เปลี่ยนแปลง
Any Image คือการรวบรวมสัญญาณของความถี่ต่างๆ ความถี่ที่สูงขึ้นจะควบคุมขอบและความถี่ต่ำจะควบคุมเนื้อหาของภาพ ขอบจะเกิดขึ้นเมื่อมีการเปลี่ยนแปลงอย่างรวดเร็วจากค่าพิกเซลหนึ่งไปเป็นค่าพิกเซลอื่นเช่น 0 และ 255 ในเซลล์ที่อยู่ติดกัน เห็นได้ชัดว่ามีการเปลี่ยนแปลงที่คมชัดและด้วยเหตุนี้ขอบและความถี่สูง สำหรับการเพิ่มความคมชัดของภาพการเปลี่ยนภาพเหล่านี้สามารถปรับปรุงเพิ่มเติมได้
วิธีหนึ่งคือการแปลงเคอร์เนลตัวกรองที่สร้างขึ้นเองกับรูปภาพ
import cv2
import numpy as np
image = cv2.imread('images/input.jpg')
kernel = np.array([[-1,-1,-1],
[-1, 9,-1],
[-1,-1,-1]])
sharpened = cv2.filter2D(image, -1, kernel) # applying the sharpening kernel to the input image & displaying it.
cv2.imshow('Image Sharpening', sharpened)
cv2.waitKey(0)
cv2.destroyAllWindows()
มีอีกวิธีหนึ่งในการลบภาพเบลอออกจากเวอร์ชันสว่าง ซึ่งจะช่วยให้ภาพคมชัดขึ้น แต่ควรทำด้วยความระมัดระวังเนื่องจากเราเพิ่งเพิ่มค่าพิกเซล ลองนึกภาพค่าพิกเซลสีเทา 190 ซึ่งหากคูณด้วย 2 น้ำหนักจะเท่ากับ 380 แต่ถูกตัดออกที่ 255 เนื่องจากช่วงพิกเซลสูงสุดที่อนุญาต นี่คือการสูญเสียข้อมูลและนำไปสู่การล้างภาพออก
addWeighted(frame, 1.5, image, -0.5, 0, image);
เพื่อความชัดเจนในหัวข้อนี้ควรทำบางประเด็น:
การทำให้ภาพคมชัดเป็นปัญหาที่ไม่เหมาะสม กล่าวอีกนัยหนึ่งการเบลอเป็นการดำเนินการที่สูญเสียและโดยทั่วไปแล้วจะไม่สามารถทำได้
ในการเพิ่มความคมชัดของภาพเดียวคุณต้องเพิ่มข้อ จำกัด (สมมติฐาน) ว่าคุณต้องการภาพประเภทใดและภาพนั้นเบลออย่างไร นี่คือพื้นที่ของสถิติภาพธรรมชาติ วิธีการลับคมจะเก็บสถิติเหล่านี้ไว้อย่างชัดเจนหรือโดยปริยายในอัลกอริทึมของพวกเขา (การเรียนรู้เชิงลึกเป็นการเข้ารหัสโดยปริยายที่สุด) วิธีการทั่วไปในการเพิ่มน้ำหนักบางระดับของการสลายตัวของพีระมิด DOG หรือ Laplacianซึ่งเป็นคำตอบทั่วไปของ Brian Burns ถือว่าการเบลอภาพแบบเกาส์ทำให้ภาพเสียหายและวิธีการถ่วงน้ำหนักนั้นเชื่อมโยงกับสมมติฐานเกี่ยวกับสิ่งที่เป็นอยู่ ในภาพเริ่มต้นด้วย
แหล่งข้อมูลอื่น ๆ อาจทำให้ปัญหามีความคมชัดขึ้น แหล่งข้อมูลทั่วไปเช่นวิดีโอของวัตถุที่กำลังเคลื่อนที่หรือการตั้งค่าหลายมุมมอง การเพิ่มความคมชัดในการตั้งค่านั้นมักเรียกว่าsuper-resolution (ซึ่งเป็นชื่อที่ไม่ดีสำหรับมัน แต่มันติดอยู่ในวงวิชาการ) มีวิธีการที่มีความละเอียดสูงใน OpenCVมานานแล้ว .... แม้ว่าโดยปกติแล้วพวกเขาจะไม่ได้ผลดีสำหรับปัญหาจริงในที่สุดฉันก็ลองดู ฉันคาดหวังว่าการเรียนรู้เชิงลึกจะให้ผลลัพธ์ที่ยอดเยี่ยมที่นี่เช่นกัน อาจจะมีคนโพสต์ในข้อคิดเห็นเกี่ยวกับสิ่งที่คุ้มค่า
ในการทำให้ภาพคมชัดขึ้นเราสามารถใช้ฟิลเตอร์ (เช่นเดียวกับคำตอบก่อนหน้านี้)
kernel = np.array([[-1, -1, -1],[-1, 8, -1],[-1, -1, 0]], np.float32)
kernel /= denominator * kernel
จะมากที่สุดเมื่อตัวส่วนเป็น 1 และจะลดลงเมื่อเพิ่มขึ้น (2.3 .. )
ตัวที่ใช้มากที่สุดคือเมื่อตัวส่วนเป็น 3
ด้านล่างนี้คือการนำไปใช้งาน
kernel = np.array([[-1, -1, -1],[-1, 8, -1],[-1, -1, 0]], np.float32)
kernel = 1/3 * kernel
dst = cv2.filter2D(image, -1, kernel)