基於DCT影像壓縮的預處理方法
方案設計:
設計一指標 I 以透過功率頻譜密度DCT之分布,並利用量測之功率頻譜密度經設計之公式後計算成ρ_mod,並調整濾波器之強度,然後對圖片壓縮前做濾波,在與普通低通濾波器與原圖做比較。
實驗步驟:
1.計算ρmod
1.像素水平方向取 7-9 個 pixel 減去DC後計算Rxx(1), Rxx(0)
2.根據ρmod 決定濾波的強度,濾掉有正ρmod的地方
3.混和原始與濾波後訊號
4.對每個像素重複以上步驟
5.垂直方向重複
6.如果是彩色,各分量皆需重複
2.濾波:
1.先算出圖片x,y方向ρ_mod
2.設計一線性低通濾波器
3.當該pixel的ρ_mod大於0時將每個pixel的ρ_mod減去ρ_th調整濾波器的強度,反之小於 0則不濾該pixel
4.將設計之濾波後結果與普通的線性低通濾波器作比較
3.source code
```
import numpy as np
import cv2
import pylab
import matplotlib.pyplot as plt
from PIL import Image
from scipy.fft import dctn, idctn
#correlation coefficient
def Rx0(input_list):
sum = 0
for x in input_list:
sum = sum + (x ** 2)
return sum
def Rx1(input_list):
sum = 0
for x in range(len(input_list) - 1):
sum = sum + input_list[x]*input_list[x+1]
return sum
#ringing effect
def calculate_ringing_effect(image_path):
# 讀取圖片
img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
# 使用高通濾波器(例如Laplacian)進行邊緣檢測
laplacian = cv2.Laplacian(img, cv2.CV_64F)
# 計算ringing effect(絕對值)
ringing_effect = np.abs(laplacian)
# 計算ringing effect的平均值
mean_ringing_effect = np.mean(ringing_effect)
return mean_ringing_effect
path='image1.jpg'
img_gray = cv2.imread('image1.jpg',cv2.IMREAD_GRAYSCALE)
img=Image.open('image1.jpg')
pixel_gray_image = img.convert('L')
image_array = np.array(pixel_gray_image)
array_size = 10
cv2.imwrite('original.jpg',img_gray)
# dct
block = np.array(image_array[ 0 , array_size])
dct_image = dctn(image_array, type=2, norm='ortho')
line_data = [dct_image[i+2][i] for i in range(array_size)]
# 讀值
pixels = list(pixel_gray_image.getdata())
img_gray.shape
x_range = 500
y_range = 500
Rxx_x = []
for m in range(y_range):
Rxx_tmp = []
for count in range(x_range):
tmp = []
down = count-4
up = count+5
for n in range(down,up):
if n >= 0 and n < x_range:
tmp.append(img_gray[m,n])
tmp_avg=tmp-np.mean(tmp)
Rxx_tmp.append(Rx1(tmp_avg)/(Rx0(tmp_avg)-0.01))
Rxx_x.append(Rxx_tmp)
correlate_x = np.array(Rxx_x)
correlate_x.shape
correlate_x
#plt.plot(correlate_x)
law_th=0.346
sum_along_axis=[]
# Read image
img_src = cv2.imread('image1.jpg',cv2.IMREAD_GRAYSCALE)
a=[1,2,5,5,5,10,7]
# Prepare the 5x5 shaped filter
kernel = np.array([[1, 1, 1, 2, 1, 1, 1],
[1, 4, 1, 4, 1, 4, 1],
[1, 1, 8, 8, 8, 1, 1],
[1, 1, 1, 16, 1, 1, 1],
[1, 1, 8, 8, 8, 1, 1],
[1, 4, 1, 4, 1, 4, 1],
[1, 1, 1, 2, 1, 1, 1]
])
kernel = kernel/sum(kernel)
#array = kernel.reshape(500,500, 7,7)
array2 = np.full((500,500,3 ,3 ), 1)
array2=array2.astype(float)
correlate_x=correlate_x.astype(float)
linear_filter_2 = cv2.boxFilter(img_src, -1, (1,1)) #linear filter
linear_filter = cv2.boxFilter(img_src, -1, (9,9)) #linear filter
blur = cv2.blur(img_src, (3,3))
for i in range(x_range):
for j in range(x_range):
if correlate_x[i][j]>0:
array2[i][j]=(array2[i][j]*(correlate_x[i][j]-law_th))
img_rst = cv2.filter2D(img_src,-1,array2[i][j])
else:
img_rst = cv2.filter2D(img_src,-1,linear_filter_2)
# Filter the source image
# Save result image
cv2.imwrite('lpf.jpg',blur)
cv2.imwrite('0.346.jpg',img_rst)
array2
lpf='lpf.jpg'
rst='0.346.jpg'
gray='original.jpg'
ringing_effect_lpf = calculate_ringing_effect(lpf)
ringing_effect_calculate = calculate_ringing_effect(rst)
ringing_effect_original = calculate_ringing_effect(gray)
print(f"Ringing Effect_original: {ringing_effect_original}")
print(f"Ringing Effect_lpf: {ringing_effect_lpf}")
print(f"Ringing Effect_calculate: {ringing_effect_calculate}")
plt.imshow(correlate_x, cmap='gray')
plt.colorbar()
plt.show()
plt.imshow(image_array,cmap='gray')
plt.colorbar()
plt.show()
#img_dct = Image.fromarray(line_data, 'L') #將matix轉為圖片
#plt.imshow() #顯示圖片
# 输出前10个像素的灰度值
for i in range(10):
print(f"像素 {i + 1} 的灰度值: {pixels[i]}")
print(f"像素 {i + 1} 的dct值: {line_data[i]}")
# 顯示圖片格式
print(type(img_gray)) #顯示img在opencv中儲存的格式
print(img_gray.shape)
#print(img_gray)
#cv2.imshow('My Image', img_gray)
#cv2.imwrite('output.jpg', img_gray)
# 畫圖
plt.plot(line_data, marker='o', linestyle='-')
plt.title('二维 DCT 折線圖')
plt.xlabel('位置')
plt.ylabel('權重')
plt.show()
# 按下任意鍵則關閉所有視窗
cv2.namedWindow('My Image', cv2.WINDOW_NORMAL)
cv2.waitKey(0)
cv2.destroyAllWindows()
```