Bộ lọc hình ảnh nào có thể được áp dụng để loại bỏ mô hình lưới từ jpeg bị hỏng?


8

Tôi có khoảng 1.400 jpeg đã bị hỏng bằng cách nào đó và đã mất hình ảnh sao lưu. Tất cả chúng dường như có cùng một kiểu đường kẻ trên mỗi đường (ví dụ, việc chia lưới không chuyển từ hình ảnh này sang hình ảnh khác.

Đây là một trong những hình ảnh này trông như thế nào:

nhập mô tả hình ảnh ở đây

Có bất kỳ kỹ thuật lọc hình ảnh nào trong Matlab đặc biệt hoặc nếu không sẽ loại bỏ hoặc làm mịn mẫu lưới này?


2
bạn có thể cho chúng tôi thêm thông tin về cách những hình ảnh này bị hỏng không? Đây là một mẫu lạ, vì nó rất cục bộ pixel, đòi hỏi độ phân giải cao trong miền tần số, có nghĩa là bộ mã hóa JPEG bị hỏng khủng khiếp, có thể?
Marcus Müller

Tôi không hoàn toàn chắc chắn, xin lỗi. Các hình ảnh là một phần của cơ sở dữ liệu đã thay đổi tay một vài lần và mọi người đã không cẩn thận như họ cần phải có (... sinh viên đại học). Theo như vấn đề pixel-local, tôi đồng ý. Trong một số bức ảnh bao gồm các bề mặt nước tối hơn, mô hình lưới rất nhẹ.
Stephen E

@ MarcusMüller: Một bộ giải mã JPEG bị hỏng khủng khiếp dường như có khả năng hơn đối với tôi, mặc dù tôi cho rằng một trong hai cách là có thể. Dù sao, dựa trên khoảng cách giữa các dòng không đều và không có 2 dòng, đối với tôi, hình ảnh có thể đã được thu nhỏ lại và được mã hóa lại sau khi tham nhũng xảy ra, vì vậy, than ôi, cố gắng sửa chúng trong Tên miền DCT có thể là vô ích. Giải pháp khắc phục của Maximilian Matthé dưới đây có lẽ là đặt cược tốt nhất của OP.
Ilmari Karonen

1
Ồ, và OP chắc chắn nên lưu một bản sao lưu của các hình ảnh trước khi cố gắng sửa chúng bằng bất kỳ cách nào, trong trường hợp ai đó muốn quay lại chúng. Tuy nhiên, inpainting luôn luôn là một hoạt động mất mát và có khả năng đưa ra sự thiên vị (vì về cơ bản, nó tạo ra dữ liệu giả để thay thế các pixel bị hỏng). Và điều tương tự cũng xảy ra đối với việc lọc trung bình hoặc loại bỏ tần số, hoặc bất cứ điều gì khác có khả năng che giấu loại thiệt hại này.
Ilmari Karonen

@IlmariKaronen Cảm ơn vì tiền boa. Chắc chắn sẽ cố gắng cẩn thận hơn với những hình ảnh này.
Stephen E

Câu trả lời:


16

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:

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây

Để 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à:

  1. phát hiện lưới điện
  2. tạo một mặt nạ mô tả các pixel bị hỏng bởi lưới
  3. 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.


Cảm ơn về thông tin bạn vừa nhập! Kết quả của bạn ở đây là thực sự tốt đẹp! Tôi sẽ thử cái này. Tuyên bố miễn trừ trách nhiệm: Tôi rất nhiều người mới trong việc xử lý hình ảnh vì vậy điều này sẽ khiến tôi đôi khi phải tự mình xử lý, nhưng sẽ đánh dấu nó được giải quyết vì nó hoạt động rất tốt với kết thúc của bạn. Trong môi trường nào bạn đang chạy thuật toán này? Tôi nghĩ rằng việc phát hiện cạnh không mong muốn trên thiết bị và cơ sở hạ tầng trong ảnh sẽ không thành vấn đề vì phần lớn các hình ảnh không bao gồm bất kỳ thứ gì và chỉ là Tundra và / hoặc nước. Làm thế nào bạn đi về việc thêm các đỉnh từ tất cả các hình ảnh?
Stephen E

Cảm ơn! Môi trường là Python và tôi vừa thêm một ghi chú về ý nghĩa của tôi với việc tổng hợp các đỉnh cho tất cả các hình ảnh.
Maximilian Matthé

3

Tôi đã thử một thuật toán thực sự đơn giản để chạy bộ lọc trung bình 3x3 trên các kênh R và G của hình ảnh đó và nó hoạt động khá tốt. nhập mô tả hình ảnh ở đây Mã python thực sự đơn giản:

import scipy.signal as sp
from scipy import ndimage

image = ndimage.imread('Ahrnl.jpg', flatten=False)
image_filtered = np.array(image)
for i in range(2) :
  image_filtered[:,:,i] = sp.medfilt2d(image[:,:,i])

Ngoài ra, bạn có thể sử dụng tính năng lọc miền tần số như được thảo luận trong câu hỏi này: /programming/34027840/removing- periodic-noise-from-an-image-USE-the-fourier-transform

Biến đổi Fourier của hình ảnh của bạn hiển thị rõ ràng một số "chấm" lặp đi lặp lại trong phổ tương ứng với nhiễu định kỳ này. nhập mô tả hình ảnh ở đây

Như Maximilian đã chỉ ra, phương pháp sau này chỉ hoạt động tốt nếu tiếng ồn là hoàn toàn định kỳ, dường như không phải là trường hợp ở đây.

Tôi đã thử chạy một bộ lọc thực sự ngu ngốc để loại bỏ các ô vuông tần số 5x5 tập trung xung quanh bội số 9 theo cả hai hướng x và y và nó (loại) loại bỏ tiếng ồn nhưng giới thiệu các tạo tác ở những vị trí không chứa tiếng ồn (ví dụ: bầu trời).

Có lẽ người ta có thể làm tốt hơn với thiết kế bộ lọc notch cẩn thận thay vì bỏ trống FFT trực tiếp ( không bao giờ làm điều đó trong thực tế! ) Và chỉ áp dụng bộ lọc trong các khu vực của hình ảnh có nhiễu (tức là không lọc bầu trời).

nhập mô tả hình ảnh ở đây


trong dòng cuối cùng của bạn, tôi tin rằng bạn chỉ cần lọc kênh màu đỏ hai lần (chỉ số cuối cùng phải là i, không phải 0)
Maximilian Matthé

@ MaximilianMatthé bắt tốt! (May mắn là mã thực tế của tôi mà tôi đã chạy là ok: P)
Atul Ingle

Về phương pháp Fourier-Transform: Điều này chỉ hoạt động đáng tin cậy, nếu lưới thực sự đều đặn (tức là cùng khoảng cách giữa tất cả các dòng). Tôi không thể (ít nhất là không nhanh chóng) tìm thấy các tham số để tôi có thể vẽ một lưới thông thường trên đầu các dòng bị hỏng. Sau đó, Phương pháp Fourier cũng sẽ không thể loại bỏ tiếng ồn không chính xác định kỳ này.
Maximilian Matthé

@ MaximilianMatthé bạn đúng - Phương pháp FFT là khó khăn vì tiếng ồn không phải là mô hình định kỳ hoàn hảo. Nhưng nó có thể làm việc với thiết kế bộ lọc notch cẩn thận. Có lẽ.
Atul Ingle

Cảm ơn về thông tin bạn vừa nhập! Tôi đã thử bộ lọc trung bình 3x3 trong Matlab và trong khi nó đã loại bỏ việc tạo lưới (phần lớn), tôi không thích giảm chi tiết của hình ảnh (chúng cần xuất hiện trong cửa sổ bật lên trên ứng dụng lập bản đồ web.
Stephen E
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.