Filter gambar mana yang dapat diterapkan untuk menghapus pola grid dari jpegs yang rusak?

8

Saya memiliki sekitar 1.400 jpeg yang entah bagaimana telah rusak dan telah kehilangan gambar cadangan. Mereka semua tampaknya memiliki pola garis grid yang sama pada masing-masing (yaitu gridding tidak bergeser dari gambar ke gambar.

Seperti inilah salah satu gambar ini:

masukkan deskripsi gambar di sini

Apakah ada teknik penyaringan gambar di Matlab khususnya atau yang akan menghapus atau menghaluskan pola gridding ini?

Stephen E
sumber
2
dapatkah Anda memberi kami informasi lebih lanjut tentang bagaimana gambar-gambar ini menjadi rusak? Ini adalah pola yang aneh, karena sangat pixel-lokal, yang membutuhkan resolusi tinggi dalam domain frekuensi, yang akan menyiratkan encoder JPEG yang rusak parah, mungkin?
Marcus Müller
Saya tidak sepenuhnya yakin, maaf. Gambar-gambar tersebut adalah bagian dari database yang telah berpindah tangan beberapa kali dan orang-orang belum berhati-hati seperti seharusnya (... undergrads). Sejauh masalah pixel-lokal, saya setuju. Dalam beberapa foto yang mencakup permukaan air yang lebih gelap, pola kisi-kisi sangat ringan.
Stephen E
@ MarcusMüller: Dekoder JPEG yang rusak parah tampaknya lebih mungkin bagi saya, meskipun saya kira kedua cara itu mungkin. Pokoknya, berdasarkan spasi yang tidak merata dan non-power-of-2 dari garis, menurut saya gambar mungkin telah ditingkatkan dan disandikan ulang setelah korupsi terjadi, jadi, sayangnya, mencoba untuk memperbaikinya di Domain DCT mungkin sia-sia. Solusi pewarnaan oleh Maximilian Matthé di bawah ini mungkin merupakan taruhan terbaik OP.
Ilmari Karonen
1
Oh, dan OP pasti harus menyimpan cadangan gambar sebelum mencoba memperbaikinya dengan cara apa pun, kalau-kalau ada orang yang ingin menganalisis ulang mereka. Pengecatan, betapapun dilakukan dengan baik, selalu merupakan operasi yang merugi, dan berpotensi menimbulkan bias (karena pada dasarnya berarti membuat data palsu untuk mengganti piksel yang rusak). Dan hal yang sama berlaku untuk penyaringan median atau penghapusan frekuensi juga, atau hal lain yang mungkin menyembunyikan kerusakan semacam ini.
Ilmari Karonen
@IlmariKaronen Terima kasih atas tipnya. Pasti akan berusaha lebih berhati-hati dengan gambar-gambar ini.
Stephen E

Jawaban:

16

Anda dapat menggunakan algoritma pewarnaan standar. Algoritma ini menggantikan piksel yang ditandai dalam gambar dengan nilai piksel yang mengelilingi piksel yang ditandai ini. Tantangannya di sini adalah untuk mendeteksi kisi (tes saya tampaknya menunjukkan bahwa itu bukan kisi yang benar-benar teratur). Jadi, saya datang dengan solusi ini:

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)

Output program adalah sebagai berikut:

masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini

Untuk mendeteksi kisi-kisi saya melakukan solusi cepat dan kotor. Dapat ditingkatkan banyak, tetapi itu menunjukkan ide awal. Alur umumnya adalah:

  1. mendeteksi grid
  2. buat topeng yang menjelaskan piksel mana yang rusak oleh kisi
  3. pasang piksel yang rusak.

Untuk inpainting saya menggunakan operasi inpaint OpenCV . Untuk mendeteksi kisi, saya melakukan deteksi tepi dalam arah X dan Y menggunakan filter Sobel. Lalu saya menambahkan semua nilai tepi dalam arah-X dan arah-Y untuk menemukan puncak, di mana garis-garis kisi berada. Lalu, saya memilih puncak tertinggi sebagai koordinat tempat garis kisi diperkirakan. Ini tidak berfungsi sempurna (misalnya tepi yang kuat pada gambar dideteksi secara salah sebagai garis kisi), tetapi itu menunjukkan ide. Hal ini dapat ditingkatkan dengan misalnya transformasi Hough untuk menemukan garis, menendang keluar tepi yang sangat kuat dll.

Atau, jika kisi-kisi benar-benar sama untuk semua gambar, maka Anda dapat melakukan deteksi kisi bersama untuk semua gambar, yang akan menghasilkan akurasi yang jauh lebih baik (cukup lakukan teknik di atas, tetapi sebelum memilih puncak, jumlahkan hasil dari semua gambar). Secara lebih rinci, Anda akan menghitung eX untuk semua gambar dan menambahkan semua eX ini menjadi satu vektor. Vektor ini akan memiliki struktur puncak yang jauh lebih jelas dan ambang dapat dilakukan dengan lebih mudah.

Maximilian Matthé
sumber
Terima kasih atas masukannya! Hasil Anda di sini sangat bagus! Saya akan coba ini. Penafian: Saya sangat pemula dalam pemrosesan gambar sehingga ini akan membutuhkan waktu untuk saya selesaikan sendiri, tetapi akan menandainya diselesaikan karena bekerja dengan sangat baik pada Anda. Di lingkungan apa Anda menjalankan algoritma ini? Saya pikir deteksi tepi yang tidak diinginkan pada instrumentasi dan infrastruktur dalam gambar tidak akan menjadi masalah karena sebagian besar gambar tidak termasuk semua itu dan hanya Tundra dan / atau air. Bagaimana Anda bisa menambahkan puncak dari semua gambar?
Stephen E
Terima kasih! Lingkungannya adalah Python dan saya baru saja menambahkan catatan tentang apa yang saya maksud dengan merangkum puncak untuk semua gambar.
Maximilian Matthé
3

Saya mencoba algoritma yang sangat sederhana untuk menjalankan filter median 3x3 pada saluran R dan G dari gambar itu dan itu bekerja dengan cukup baik. masukkan deskripsi gambar di sini Kode python sangat sederhana:

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])

Atau Anda dapat menggunakan pemfilteran domain frekuensi seperti yang dibahas dalam pertanyaan ini: /programming/34027840/removing- periodic-noise-from-an-image-using-the-fourier-transform

Transformasi Fourier dari gambar Anda dengan jelas menunjukkan beberapa "titik" berulang dalam spektrum yang sesuai dengan derau periodik ini. masukkan deskripsi gambar di sini

Seperti yang Maximilian tunjukkan, metode yang terakhir ini hanya berfungsi dengan baik jika kebisingannya sangat periodik, yang tampaknya tidak menjadi masalah di sini.

Saya mencoba menjalankan filter yang benar-benar bodoh yang mengeluarkan kotak frekuensi 5x5 kuadrat yang berpusat di sekitar kelipatan 9 di kedua arah x dan y dan itu (semacam) menekan suara tetapi memperkenalkan artefak di lokasi yang tidak mengandung kebisingan (misalnya. langit).

Seseorang mungkin dapat melakukan lebih baik dengan desain takik-saringan yang hati-hati alih-alih secara langsung memusatkan nampan FFT ( jangan pernah melakukan itu dalam praktik! ) Dan hanya menerapkan filter di wilayah gambar di mana noise hadir (yaitu jangan menyaring langit).

masukkan deskripsi gambar di sini

Atul Ingle
sumber
di baris terakhir Anda, saya yakin Anda hanya memfilter saluran merah dua kali (indeks terakhir seharusnya i, bukan 0)
Maximilian Matthé
@ MaximilianMatthé tangkapan bagus! (Untungnya kode aktual saya yang saya jalankan ok: P)
Atul Ingle
Mengenai metode Fourier-Transform: Ini hanya bekerja dengan andal, jika grid benar-benar teratur (yaitu jarak yang sama antara semua garis). Saya tidak bisa (setidaknya tidak dengan cepat) menemukan parameter sehingga saya bisa menggambar grid biasa di atas baris yang rusak. Kemudian, Metode Fourier juga tidak akan dapat menghilangkan kebisingan yang tidak terlalu periodik ini.
Maximilian Matthé
@ MaximilianMatthé Anda benar - Metode FFT rumit karena suaranya tidak sempurna secara periodik. Tapi itu mungkin bekerja dengan desain takik filter yang cermat. Mungkin.
Atul Ingle
Terima kasih atas masukannya! Saya memang mencoba filter median 3x3 di Matlab dan sementara itu menghapus gridding (kebanyakan) saya tidak suka penurunan detail gambar (mereka perlu muncul dalam pop-up pada aplikasi pemetaan web.
Stephen E