---
# System prepended metadata

title: '   基於DCT影像壓縮的預處理方法'

---

                基於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()

```
