Bạn có thể sử dụng một thuật toán inpainting tiêu chuẩn. Các thuật toán này thay thế các pixel được đánh dấu trong một hình ảnh bằng các giá trị pixel bao quanh các pixel được đánh dấu này. Thách thức ở đây là phát hiện lưới điện (các thử nghiệm của tôi dường như cho thấy rằng nó không phải là lưới hoàn toàn thông thường). Vì vậy, tôi đã đưa ra giải pháp này:
from PIL import Image
import requests
from io import BytesIO
import cv2
url = "http://i.stack.imgur.com/Ahrnl.jpg"
response = requests.get(url)
img = Image.open(BytesIO(response.content))
plt.imshow(img)
A = np.array(img)
A2 = A.copy()
A_gray = cv2.cvtColor(A, cv2.COLOR_RGB2GRAY)
# Do some rough edge detection to find the grid
sX = cv2.Sobel(A_gray, cv2.CV_64F, 1, 0, ksize=3)
sY = cv2.Sobel(A_gray, cv2.CV_64F, 0, 1, ksize=3)
sX[sX<0] = 0
sY[sY<0] = 0
plt.subplot(221)
plt.imshow(sX)
plt.subplot(222)
plt.imshow(sY)
plt.subplot(223)
# the sum operation projects the edges to the X or Y-axis.
# The 0.2 damps the high peaks a little
eX = (sX**.2).sum(axis=0)
eX = np.roll(eX, -1) # correct for the 1-pixel offset due to Sobel filtering
plt.plot(eX)
plt.subplot(224)
eY = (sY**.2).sum(axis=1)
eY = np.roll(eY, -1)
plt.plot(eY)
mask = np.zeros(A2.shape[:2], dtype=np.uint8)
mask[eY>480,:] = 1
mask[:, eX>390] = 1
A2[mask.astype(bool),:] = 255
plt.figure()
plt.subplot(221)
plt.imshow(A)
plt.subplot(222)
plt.imshow((A2))
restored = cv2.inpaint(A, mask, 1, cv2.INPAINT_NS)
plt.subplot(223)
plt.imshow(restored)
Đầu ra của chương trình như sau:
Để phát hiện lưới tôi đã làm một giải pháp nhanh và bẩn. Nó có thể được cải thiện rất nhiều, nhưng nó cho thấy ý tưởng ban đầu. Lưu lượng chung là:
- phát hiện lưới điện
- tạo một mặt nạ mô tả các pixel bị hỏng bởi lưới
- inpaint các pixel bị hỏng.
Để inpainting tôi đã sử dụng hoạt động inpaint OpenCV . Để phát hiện lưới, tôi đã thực hiện phát hiện cạnh theo hướng X và Y bằng bộ lọc Sobel. Sau đó, tôi thêm tất cả các giá trị cạnh theo hướng X và hướng Y để tìm các đỉnh, trong đó các đường lưới. Sau đó, tôi chọn các đỉnh cao nhất làm tọa độ nơi các đường lưới được ước tính. Nó không hoạt động hoàn hảo (ví dụ: các cạnh mạnh trong ảnh bị phát hiện sai dưới dạng đường lưới), nhưng nó cho thấy ý tưởng. Nó có thể được cải thiện bằng cách chuyển đổi Hough để tìm đường, đá ra các cạnh rất mạnh, v.v.
Ngoài ra, nếu lưới thực sự giống nhau cho tất cả các hình ảnh, thì bạn có thể thực hiện phát hiện lưới chung cho tất cả các hình ảnh, điều này sẽ mang lại độ chính xác cao hơn nhiều (chỉ cần thực hiện kỹ thuật trên, nhưng trước khi chọn các đỉnh, tổng hợp kết quả từ tất cả hình ảnh). Chi tiết hơn, bạn sẽ tính toán eX cho tất cả các hình ảnh và cộng tất cả các eX này lại với nhau thành một vectơ. Vectơ này sẽ có cấu trúc đỉnh rõ ràng hơn nhiều và việc ngưỡng có thể được thực hiện dễ dàng hơn.