I was trying to use compressed sensing technology in image processing. Basically, I did a code in Python(Spyder IDE) which takes an image, compress the image and reconstructs it.
I tried with the lasso tool but found that due to insufficient ram storage, the code was crashing every time I was trying to run it. So I switched to ECOS method. But now the problem is that the quality of the recovered image seems to have reduced enormously. If I try to increase the clarity, the sparse signal size increases beyond the original image size. So is there any way to enhance the quality(clarity) of the recovered image while keeping the size of the sparse signal below the original image size? This is my code:
import numpy as np
import cv2
import matplotlib.pyplot as plt
from scipy.fftpack import dct, idct
from scipy.sparse import csr_matrix, save_npz, load_npz
import cvxpy as cp
import os
def load_image(path):
img = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
if img is None:
raise FileNotFoundError(f"Unable to load image from path: {path}")
return img / 255.0
def apply_dct(img):
return dct(dct(img.T, norm='ortho').T, norm='ortho')
def apply_idct(img_dct):
return idct(idct(img_dct.T, norm='ortho').T, norm='ortho')
def compress_measurements(signal, compression_ratio):
M, N = signal.shape
K = int(M * N * compression_ratio)
indices = np.random.choice(M * N, K, replace=False)
measurements = np.zeros(M * N)
measurements[indices] = signal.flatten()[indices]
return measurements.reshape((M, N)), indices
def l1_reconstruction(measurements, indices, shape):
M, N = shape
K = len(indices)
# Measurement vector
y = measurements.flatten()[indices]
# Sensing matrix
A = csr_matrix((np.ones(K), (np.arange(K), indices)), shape=(K, M * N))
# Define the optimization problem
x = cp.Variable(M * N)
objective = cp.Minimize(cp.norm(x, 1))
constraints = [A @ x == y]
problem = cp.Problem(objective, constraints)
problem.solve(solver=cp.ECOS, verbose=True)
return x.value.reshape(shape)
def save_sparse_array(array, filename):
sparse_array = csr_matrix(array)
save_npz(filename, sparse_array)
def load_sparse_array(filename, shape):
sparse_array = load_npz(filename)
return sparse_array.toarray().reshape(shape)
def print_file_size(filename):
size_bytes = os.path.getsize(filename)
size_kb = size_bytes / 1024
print(f"Size of '{filename}': {size_kb:.2f} KB")
def main():
# Load the image
img = load_image('/content/img 1.jpg')
# Apply DCT
img_dct = apply_dct(img)
# Compress Measurements
compression_ratio = 0.7 # Increase the compression ratio for better quality
measurements_dct, indices_dct = compress_measurements(img_dct, compression_ratio)
# Reconstruct the image using L1 minimization
reconstructed_dct = l1_reconstruction(measurements_dct, indices_dct, img.shape)
# Apply IDCT to get the reconstructed image
img_reconstructed_dct = apply_idct(reconstructed_dct)
# Save the original DCT, reconstructed DCT, original image, and reconstructed image
save_sparse_array(img_dct, '/content/original_dct.npz')
save_sparse_array(reconstructed_dct, '/content/reconstructed_dct.npz')
cv2.imwrite('/content/original_image.jpg', (img * 255).astype(np.uint8))
cv2.imwrite('/content/reconstructed_image.jpg', (img_reconstructed_dct * 255).astype(np.uint8))
# Print file sizes
print_file_size('/content/original_dct.npz')
print_file_size('/content/reconstructed_dct.npz')
print_file_size('/content/original_image.jpg')
print_file_size('/content/reconstructed_image.jpg')
# Plot the results
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.imshow(img, cmap='gray')
plt.title('Original Image')
plt.subplot(1, 2, 2)
plt.imshow(img_reconstructed_dct, cmap='gray')
plt.title('Reconstructed DCT Image')
plt.show()
if __name__ == "__main__":
main()