Tôi đã viết một số mã Python (xin lỗi không phải C++) sẽ cho phép làm nổi bật mặt nạ thích ứng mặt nạ. Nó không phải là rất nhanh, nhưng nó làm những gì bạn muốn, và bạn có thể sử dụng nó làm cơ sở cho mã C++. Nó hoạt động như sau:
- Đặt pixel bị che khuất trong hình ảnh về 0.
- Xác định số lượng hàng xóm được che giấu trong khối chập đối với mỗi pixel.
- Thực hiện chuyển đổi và tính trung bình theo số lượng hàng xóm không được che giấu trong khối. Điều này mang lại giá trị trung bình trong khối vùng lân cận pixel.
- Ngưỡng, bằng cách so sánh hình ảnh với các giá trị khu vực trung bình,
mean_conv
- Thêm phần mặt nạ (không được ngưỡng) của hình ảnh trở lại.
Những hình ảnh hiển thị, hình ảnh ban đầu, mặt nạ, hình ảnh chế biến thức.
Dưới đây là các mã:
import cv
import numpy
from scipy import signal
def thresh(a, b, max_value, C):
return max_value if a > b - C else 0
def mask(a,b):
return a if b > 100 else 0
def unmask(a,b,c):
return b if c > 100 else a
v_unmask = numpy.vectorize(unmask)
v_mask = numpy.vectorize(mask)
v_thresh = numpy.vectorize(thresh)
def block_size(size):
block = numpy.ones((size, size), dtype='d')
block[(size - 1)/2, (size - 1)/2] = 0
return block
def get_number_neighbours(mask,block):
'''returns number of unmasked neighbours of every element within block'''
mask = mask/255.0
return signal.convolve2d(mask, block, mode='same', boundary='symm')
def masked_adaptive_threshold(image,mask,max_value,size,C):
'''thresholds only using the unmasked elements'''
block = block_size(size)
conv = signal.convolve2d(image, block, mode='same', boundary='symm')
mean_conv = conv/get_number_neighbours(mask,block)
return v_thresh(image, mean_conv, max_value,C)
image = cv.LoadImageM("image.png", cv.CV_LOAD_IMAGE_GRAYSCALE)
mask = cv.LoadImageM("mask.png", cv.CV_LOAD_IMAGE_GRAYSCALE)
#change the images to numpy arrays
original_image = numpy.asarray(image)
mask = numpy.asarray(mask)
# Masks the image, by removing all masked pixels.
# Elements for mask > 100, will be processed
image = v_mask(original_image, mask)
# convolution parameters, size and C are crucial. See discussion in link below.
image = masked_adaptive_threshold(image,mask,max_value=255,size=7,C=5)
# puts the original masked off region of the image back
image = v_unmask(original_image, image, mask)
#change to suitable type for opencv
image = image.astype(numpy.uint8)
#convert back to cvmat
image = cv.fromarray(image)
cv.ShowImage('image', image)
#cv.SaveImage('final.png',image)
cv.WaitKey(0)
Sau khi viết những dòng này tôi thấy this great link rằng có một lời giải thích tốt với nhiều mẫu hình ảnh, tôi đã sử dụng hình ảnh văn bản của họ đối với ví dụ trên.
Lưu ý. Mặt nạ gắt gỏng dường như không được tôn trọng bởi scipy signal.convolve2d()
, vì vậy các cách giải quyết ở trên là cần thiết.
Cảm ơn bạn rất nhiều vì câu trả lời của bạn. Tôi đang điều tra đề xuất của bạn. Quentin –
@Quentin Geissmann - Bạn đã làm cho nó hoạt động trong mã C++ của bạn? – fraxel
Tôi nghĩ rằng tôi hiểu cách thực hiện mà không làm cho nó rất chậm ... Nhưng chưa được triển khai. :) cảm ơn bạn –