<jupyter_start><jupyter_text>Penerapan Dekomposisi Nilai Singular Untuk Mengkompresi Citra<jupyter_code>import sys
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
import ipywidgets as widgets
from numpy.core.fromnumeric import size<jupyter_output><empty_output><jupyter_text>Paket OpenCV dapat mengambil data dari gambar, gif, maupun video. Fungsi `imread` akan mengembalikan nilai berupa `numpy.array`.<jupyter_code># Specify path relative to current file.
img_path = "./../res/Test.png"
# Read image and convert to the 3 channel BGR color.
img = cv.imread(img_path, cv.IMREAD_COLOR)

if img is None:
    sys.exit("Image could not be read.")
print("Image properties:\n",
    f"Shape: {img.shape}\n",
    f"Size:  {img.size:,} bytes")

# OpenCV uses BGR format while matplotlib uses RGB format.
img_plot = plt.imshow(cv.cvtColor(img, cv.COLOR_BGR2RGB))
plt.show()<jupyter_output><empty_output><jupyter_text>Untuk memudahkan perhitungan, gambar yang awalnya memiliki tiga kanal warna diubah menjadi format keabuan yang memiliki satu kanal warna.<jupyter_code># Convert image into single channel greyscale format.
imgGrey = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
print("Image properties:\n",
    f"Shape: {imgGrey.shape}\n",
    f"Size:  {imgGrey.size:,} bytes")

imgGrey_plot = plt.imshow(imgGrey)
imgGrey_plot.set_cmap('gray')
plt.show()<jupyter_output><empty_output><jupyter_text>Dekomposisi Nilai Singular

**Dekomposisi nilai singular** adalah faktorisasi matriks persegi panjang berukuran $m \times n$ menjadi matrix vektor singular $U$, $V$ dan matriks diagonal nilai singular $\Sigma$.

$$
X = U \Sigma V^\top
$$<jupyter_code># Singular value decomposition
U, s, Vt = np.linalg.svd(imgGrey, full_matrices=False)
S = np.diag(s)

rSlider = widgets.IntSlider(
    value=s.size//2.41,
    min=0,
    max=s.size,
    step=s.size//100,
    description="Rank: ",
)
rText = widgets.IntText(description="Value: ")
widgets.link((rSlider, "value"), (rText, "value"))
widgets.VBox([rSlider, rText])<jupyter_output><empty_output><jupyter_text>Rekonstruksi Gambar

Jika $r$ kolom pertama matriks $U$, r nilai singular pertama matriks diagonal $\Sigma$, dan r kolom pertama matriks $V^\top$ dikalikan. Maka akan didapat nilai perkiraan matriks semula dari gambar yang didekomposisi.<jupyter_code># Matrix reconstruction
imgApprox = U[:, :rSlider.value] @ S[0:rSlider.value, :rSlider.value] @ Vt[:rSlider.value, :]
print("Matrix properties:")
print("U:\n",
    f"Shape: {U[:, :rSlider.value].shape}\n",
    f"Size:  {U[:, :rSlider.value].size:,} bytes")
print("S:\n",
    f"Shape: {S[0:rSlider.value, :rSlider.value].shape}\n",
    f"Size:  {S[0:rSlider.value, :rSlider.value].size:,} bytes")
print("S:\n",
    f"Shape: {Vt[:rSlider.value, :].shape}\n",
    f"Size:  {Vt[:rSlider.value, :].size:,} bytes")
print(f"Total size: {U[:, :rSlider.value].size + S[0:rSlider.value, :rSlider.value].size + Vt[:rSlider.value, :].size:,} bytes")

imgApprox_plot = plt.imshow(imgApprox)
imgApprox_plot.set_cmap('gray')
plt.title('r = ' + str(rSlider.value))
plt.show()
plt.figure(1)
plt.semilogy(np.diag(S))
plt.title("Singular Values")
plt.show()

plt.figure(2)
plt.plot(np.cumsum(np.diag(S))/np.sum(np.diag(S)))
plt.title("Singular Values: Cumulative Sum")
plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.15008933889219775, 'fraction_numerical': 0.005062537224538415, 'mean_word_length': 4.966252220248668, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '201744', 'license': 'MIT', 'n_tokens_mistral': 1342, 'n_tokens_neox': 1343, 'n_words': 282, 'path': '03-python-scientific-computation/src/201-compression.ipynb', 'repo_name': 'N4Z01xmn01NmZ/test-fyp', 'size': '3358'}