Istnieje wiele możliwości celowego obniżenia jakości obrazów. W ramach tego materiału mamy do wyboru kilka rodzajów modyfikacji:
- Kompresja stratna JPEG,
- Rozmywanie obrazu,
- Zaszumienie obrazu.
Jak modyfikować obrazy
Wszystkie modyfikacje będziemy nanosić przy wykorzystaniu biblioteki OpenCV wewnątrz skryptu w Pythonie. Starać się tak dobierać parametry, aby według was różnice były według was widoczne, ale nie oczywiste. Czyli testowany powinien być w stanie rozróżniać obrazy, ale nie tak, żeby wszystkie były albo maksymalnie zniekształcone, albo nieróżniące się od oryginału. Wszystkie zmodyfikowane obrazy można zapisywać do plików bezstratnych np. .png
, aby je potem wczytywać podczas dalszych badań.
Kompresja JPEG
Efekt kompresji JPEG możemy osiągnąć za pomocą kodowania wewnątrz pamięci, co umożliwia zarówno zapisanie, jak i wyświetlenie zmodyfikowanego obrazu. Parametrem, jakim możemy sterować jakością naszej kompresji, jest jakość kompresji JPEG. Jest ona wartością od \(0-100\) (\(%\)). Domyślna wartość to \(95\), więc najlepiej testować zakres jakości w przedziale \(5-80\) (najlepiej nawet \(5-65\)), bo jak sami wiecie z zajęć z JPGE nawet przy \(50%\) jakości za bardzo nie widać straty jakości na pierwszy rzut oka.
=cv2.imread('0000.png')
img= [int(cv2.IMWRITE_JPEG_QUALITY), 50]
encode_param = cv2.imencode('.jpg', img, encode_param)
result, encimg = cv2.imdecode(encimg, 1)
decimg
= plt.subplots(1, 2 , sharey=True )
fig, axs 0].imshow(img)
axs[1].imshow(decimg)
axs[
'0000_1.png',decimg) cv2.imwrite(
Rozmywanie obrazu
Jeżeli chodzi o rozmywanie obrazu mamy do dyspozycji różne zestawy funkcji i rodzajów rozmyć. Każde z nich dysponuje innymi parametrami. Mamy do dyspozycji między innymi:
- Filtrację uśredniającą (
cv2.blur
) - jako parametr przyjmuje rozmiar okna filtru uśredniającego, - rozmycie gaussowskie (
cv2.GaussianBlur
) - dwa parametry rozmiar filtru, jak również parametrsigma
dla osi X, jak również dla osi Y, - filtr medianowy (
cv2.medianBlur
) - jako parametr podaje się tutaj pojedynczą wartość jako rozmiar maski filtru, - filtr bilateralny (
cv2.bilateralFilter
) - tutaj mamy więcej parametrów rozmiar oraz dwiesigma
(jak w filtrze Gaussa) dla Koloru i przestrzeni.
Tutaj można zarówno badać różnice pomiędzy różnymi filtrami, jak i również można wybrać jeden z filtrów i przetestować go dla różnych parametrów. Więcej informacji na temat filtrów można znaleźć w tutorialu i dokumentacji
= (5,5) # rozmiar rdzenia obliczeń
kernal_size = cv2.blur(img,kernal_size) # tu sterujecie tylko rozmiarem rdzenia
blur = cv2.GaussianBlur(img,kernal_size,sigmaX,SigmaY) # Tu można streować zrówno rozmiarem rdzenia jak i sigmami w obu wymiarach
blur = cv2.medianBlur(img,5) # tu można sterować rozmiarem ale tylko w ograniczonym zakresie
median = cv2.bilateralFilter(img,5,sigmaColor,sigmaSpace) # tu mozna sterować zarówno rozamiarem jak i sigmami dla koloru i przestrzeni blur
Zaszumienie obrazu
Dodawanie szumu do obrazu polega na odchylaniu wartości pikseli obrazu, zaburzając go w sposób losowy. Możemy generować szum za pomocą różnych generatorów liczb losowych. Dwie informacje w ramach przypomnienia: Pamiętajcie, że nie wszystkie generatory dają wartości wycentrowane na 0, dlatego czasem trzeba je wyśrodkować. Drugie przypomnienie to fakt, że jeżeli przekroczymy wartości skrajne uint8
, to wartości będą zastępowane w sposób cykliczny, czyli \(255+5=0+5\) oraz \(0-55=255-55\), co może być niepożądanym efektem. Tutaj również można porównywać kilka różnych metod albo sprawdzić jedną metodę dla różnych parametrów. Stopień zaszumienia możemy regulować za pomocą jakiegoś parametru alpha
.
=0.5 # 0-1
alpha
= 25 # tym można sterować
sigma = np.random.normal(0,sigma,(img.shape))
gauss = (img + alpha * gauss).clip(0,255).astype(np.uint8)
noisy1
=0.01 # małe wartoci
beta= len(np.unique(img))
vals = beta * 2 ** np.ceil(np.log2(vals))
vals = (np.random.poisson(img * vals) / float(vals)).clip(0,255).astype(np.uint8)
noisy2
=[-25,25] #zakres szumu
Noise_range= (Noise_range[1]-Noise_range[0])*np.random.random((img.shape))+Noise_range[0]
rand = (img + alpha * rand).clip(0,255).astype(np.uint8) noisy3
Inne generatory liczb losowych, które mogą wam się przydać (doczytać w dokumentacji):
I na koniec parametryczny generator szumu sól i pieprz:
def noise_SnP(img,S=255,P=0,rnd=(333,9999)):
= img.shape
r , c = random.randint(rnd[0], rnd[1])
number_of_pixels for i in range(number_of_pixels):
=random.randint(0, r - 1)
y=random.randint(0, c - 1)
x= S
img[y][x] = random.randint(rnd[0], rnd[1])
number_of_pixels for i in range(number_of_pixels):
=random.randint(0, r - 1)
y=random.randint(0, c - 1)
x= P
img[y][x] return img