<center><font size="10">電腦視覺1.0</font></center> [toc] :::info :bulb: 名詞解釋只挑幾個並簡短敘述 ::: # 作業一 ## 數位影像處理技術 **影像擷取**:由實體擷取影像,`可使用數位相機、掃描器、CT、雷達` **影像增強**:針對數位影像進行運算處理,符合特定需求的技術,`如增加對比度、去雜訊。` **影像還原**:目標是從受損或退化的圖象中,恢復出原始的、高品質的版本。 **影像壓縮**:把不必要的或多餘的資訊去除,保留重要資訊,藉以節省資料量的技術。 ## 數位視訊處理技術 **視訊擷取**:由實體擷取連續的影像,這些影像依照一定速率播放,就形成視訊。 **取樣率轉換**:改變信號的取樣頻率或速率。`如音樂的96khz轉成44.1khz。` **運動估測**:分析視訊中物體或場景的運動。 **視訊壓縮**:將體量巨大的視訊數據進行大比例壓縮,從而實現高校傳輸和存儲的技術。 **視訊增強**:一種處理視訊素材以提高其質量、清晰度、對比度和視覺效果的技術。 **運動偵測**:一種視覺技術,旨在檢測和識別視訊中的運動或動態物體。 # 作業二 ## 色彩模式 **RGB**:分別代表紅綠藍,一種加性模型,混合紅綠藍可以產生其他顏色。 **HSV**:表色相、飽和度、明度。 **YCbCr**:表亮度、藍色差、紅色差。 ## 數位影像格式 **GIF**:無損壓縮的格式,8位元色彩深度 **PNG**:無損壓縮的格式,旨在取代GIF,支援更多顏色,更好的壓縮效率。 **JPEG**:有損壓縮的格式,所以檔案更小。 **BMP**:不壓縮的格式,因為不壓縮,所以文件大小較大。 ## 隱像術 原影像為 | 7 | 5 | |:------:|:------:| | **17** | **51** | 隱藏下列浮水印 | 0 | 1 | |:-----:|:-----:| | **1** | **0** | 原影像轉成2進位 7 = 111 5 = 101 17 = 10001 51 = 110011 把每格2進位的最後一位改成矩陣中的值 7 = 11<font color="blue">1</font> -> 11<font color="red">0</font> = ||6|| 5 = 10<font color="blue">1</font> -> 10<font color="red">1</font> = ||5|| 17 = 1000<font color="blue">1</font> -> 1000<font color="red">1</font> = ||17|| 51 = 11001<font color="blue">1</font> -> 11001<font color="red">0</font> = ||50|| :::spoiler 答 | 6 | 5 | |:------:|:------:| | **17** | **50** | ::: # 作業三 原影像為 面罩為3x3 | 101 | 105 | 106 | 110 | 200 | |:---:|:---:|:---:|:---:|:---:| | 103 | 101 | 120 | 200 | 110 | | 101 | 105 | 210 | 101 | 105 | | 108 | 200 | 125 | 250 | 111 | | 200 | 122 | 120 | 111 | 101 | ## 平滑法 :::spoiler 點我顯示python程式碼 修改自chatgpt ```python= # 原始矩陣A matrix_A = [ [101, 105, 106, 110, 200], [103, 101, 120, 200, 110], [101, 105, 210, 101, 105], [108, 200, 125, 250, 111], [200, 122, 120, 111, 101] ] # 初始化矩陣B,與矩陣A相同 matrix_B = [[num for num in row] for row in matrix_A] # 定義中值法函數 def apply_median_filter(matrix): for i in range(1, 4): for j in range(1, 4): # 取得9個數字 sub_matrix = [ matrix[i-1][j-1], matrix[i-1][j], matrix[i-1][j+1], matrix[i][j-1], matrix[i][j], matrix[i][j+1], matrix[i+1][j-1], matrix[i+1][j], matrix[i+1][j+1] ] # 將9個數字相加除9 sum_matrix = round(sum(sub_matrix)/9) # 將數字覆蓋到B矩陣的相對應位置 matrix_B[i][j] = sum_matrix return matrix_B matrix_B = apply_median_filter(matrix_A) # 輸出矩陣B print("處理後的矩陣B:") for row in matrix_B: print(" ".join(map(str, row))) ``` ::: <br> 平滑法方法: 計算面罩內的數字平均值,替代面罩中心點。 | <font color="blue">101</font> | <font color="blue">105</font> | <font color="blue">106</font> | 110 | 200 | |:-----------------------------:|:-----------------------------:|:-----------------------------:|:---:|:---:| | <font color="blue">103</font> | <font color="blue">101</font> | <font color="blue">120</font> | 200 | 110 | | <font color="blue">101</font> | <font color="blue">105</font> | <font color="blue">210</font> | 101 | 105 | | 108 | 200 | 125 | 250 | 111 | | 200 | 122 | 120 | 111 | 101 | (101+105+106+103+101+120+101+105+210)/9≈117 | 101 | 105 | 106 | 110 | 200 | |:---:|:---:|:---:|:---:|:---:| | 103 | <font color="red">117</font> | 120 | 200 | 110 | | 101 | 105 | 210 | 101 | 105 | | 108 | 200 | 125 | 250 | 111 | | 200 | 122 | 120 | 111 | 101 | 跑過全圖。==都使用原影像進行計算==。 :::spoiler 答 | 101 | 105 | 106 | 110 | 200 | |:---:|:---:|:---:|:---:|:---:| | 103 | <font color="red">117</font> | <font color="red">129</font> | <font color="red">140</font> | 110 | | 101 | <font color="red">130</font> | <font color="red">157</font> | <font color="red">148</font> | 105 | | 108 | <font color="red">143</font> | <font color="red">149</font> | <font color="red">137</font> | 111 | | 200 | 122 | 120 | 111 | 101 | ::: ## 中值法 :::spoiler 點我顯示python程式碼 修改自chatgpt ```python= # 原始矩陣A matrix_A = [ [101, 105, 106, 110, 200], [103, 101, 120, 200, 110], [101, 105, 210, 101, 105], [108, 200, 125, 250, 111], [200, 122, 120, 111, 101] ] # 初始化矩陣B,與矩陣A相同 matrix_B = [[num for num in row] for row in matrix_A] # 定義中值法函數 def apply_median_filter(matrix): for i in range(1, 4): for j in range(1, 4): # 取得9個數字 sub_matrix = [ matrix[i-1][j-1], matrix[i-1][j], matrix[i-1][j+1], matrix[i][j-1], matrix[i][j], matrix[i][j+1], matrix[i+1][j-1], matrix[i+1][j], matrix[i+1][j+1] ] # 將9個數字排序 sub_matrix.sort() # 將排序後的第5個數字覆蓋到B矩陣的相對應位置 matrix_B[i][j] = sub_matrix[4] return matrix_B matrix_B = apply_median_filter(matrix_A) # 輸出矩陣B print("處理後的矩陣B:") for row in matrix_B: print(" ".join(map(str, row))) ``` ::: <br> 中值法方法: 對面罩內排序,序列中位數替代面罩中心點。 | <font color="blue">101</font> | <font color="blue">105</font> | <font color="blue">106</font> | 110 | 200 | |:-----------------------------:|:-----------------------------:|:-----------------------------:|:---:|:---:| | <font color="blue">103</font> | <font color="blue">101</font> | <font color="blue">120</font> | 200 | 110 | | <font color="blue">101</font> | <font color="blue">105</font> | <font color="blue">210</font> | 101 | 105 | | 108 | 200 | 125 | 250 | 111 | | 200 | 122 | 120 | 111 | 101 | 序列為[101, 101, 101, 103, <font color="red">105</font>, 105, 106, 120, 210] | 101 | 105 | 106 | 110 | 200 | |:---:|:---:|:---:|:---:|:---:| | 103 | <font color="red">105</font> | 120 | 200 | 110 | | 101 | 105 | 210 | 101 | 105 | | 108 | 200 | 125 | 250 | 111 | | 200 | 122 | 120 | 111 | 101 | 跑過全圖。==都使用原影像進行計算==。 :::spoiler 答 | 101 | 105 | 106 | 110 | 200 | |:---:|:---:|:---:|:---:|:---:| | 103 | <font color="red">105</font> | <font color="red">106</font> | <font color="red">110</font> | 110 | | 101 | <font color="red">108</font> | <font color="red">125</font> | <font color="red">120</font> | 105 | | 108 | <font color="red">122</font> | <font color="red">122</font> | <font color="red">111</font> | 111 | | 200 | 122 | 120 | 111 | 101 | ::: ## 中央加權中值法 :::spoiler 點我顯示python程式碼 修改自chatgpt ```python= # 原始矩陣A matrix_A = [ [101, 105, 106, 110, 200], [103, 101, 120, 200, 110], [101, 105, 210, 101, 105], [108, 200, 125, 250, 111], [200, 122, 120, 111, 101] ] # 初始化矩陣B,與矩陣A相同 matrix_B = [[num for num in row] for row in matrix_A] # 加權值 W = 5 Wvalue = W-1 # 定義中值法函數 def apply_median_filter(matrix): for i in range(1, 4): for j in range(1, 4): # 取得9個數字 sub_matrix = [ matrix[i-1][j-1], matrix[i-1][j], matrix[i-1][j+1], matrix[i][j-1], matrix[i][j], matrix[i][j+1], matrix[i+1][j-1], matrix[i+1][j], matrix[i+1][j+1] ] # 多算加權值的次數 sub_matrix.extend([matrix[i][j]] * Wvalue) # 排序 sub_matrix.sort() # 將數字覆蓋到B矩陣的相對應位置 matrix_B[i][j] = sub_matrix[6] return matrix_B matrix_B = apply_median_filter(matrix_A) # 輸出矩陣B print("處理後的矩陣B:") for row in matrix_B: print(" ".join(map(str, row))) ``` ::: <br> 中央加權中值法方法: 對面罩內排序,再將中心點複製`加權值-1`次,序列中位數替代面罩中心點。 | <font color="blue">101</font> | <font color="blue">105</font> | <font color="blue">106</font> | 110 | 200 | |:-----------------------------:|:-----------------------------:|:-----------------------------:|:---:|:---:| | <font color="blue">103</font> | <font color="blue">101</font> | <font color="blue">120</font> | 200 | 110 | | <font color="blue">101</font> | <font color="blue">105</font> | <font color="blue">210</font> | 101 | 105 | | 108 | 200 | 125 | 250 | 111 | | 200 | 122 | 120 | 111 | 101 | 101, 101, 101, 101, 101, 101, <font color="red">101</font>, 103, 105, 105, 106, 120, 210 :::info 有`加權值`個101是中心點的數 ::: | 101 | 105 | 106 | 110 | 200 | |:---:|:---:|:---:|:---:|:---:| | 103 | <font color="red">101</font> | 120 | 200 | 110 | | 101 | 105 | 210 | 101 | 105 | | 108 | 200 | 125 | 250 | 111 | | 200 | 122 | 120 | 111 | 101 | 跑過全圖。==都使用原影像進行計算==。 :::spoiler 答 | 101 | 105 | 106 | 110 | 200 | |:---:|:---:|:---:|:---:|:---:| | 103 | <font color="red">101</font> | <font color="red">120</font> | <font color="red">200</font> | 110 | | 101 | <font color="red">105</font> | <font color="red">200</font> | <font color="red">110</font> | 105 | | 108 | <font color="red">200</font> | <font color="red">125</font> | <font color="red">125</font> | 111 | | 200 | 122 | 120 | 111 | 101 | ::: # 作業四 ## RGB轉YIQ | (30,50,80) | (40,60,70) | |:------------:|:-------------:| | (50,100,150) | (60,90,160) | | (10,20,120) | (250,200,110) | :::info :bulb: 公式為: Y=0.299R+0.587G+0.114B I=0.596R-0.274G-0.322B Q=0.211R-0.523G+0.312B ::: :::spoiler 點我顯示python程式碼 修改自chatgpt ```python= def rgb_to_yiq(r, g, b): y = 0.299 * r + 0.587 * g + 0.114 * b i = 0.596 * r - 0.274 * g - 0.322 * b q = 0.211 * r - 0.523 * g + 0.312 * b return y, i, q # 從控制台輸入RGB值,用空格分隔 rgb_input = input("請輸入RGB值(以空格分隔): ") r, g, b = map(int, rgb_input.split()) # 轉換為YIQ顏色空間 y, i, q = rgb_to_yiq(r, g, b) # 輸出結果 print("Y: {:.2f}".format(y)) print("I: {:.2f}".format(i)) print("Q: {:.2f}".format(q)) ``` ::: <br> :::spoiler 答 | (47.4 , -21.6 , 5.1) | (55.2 , -15.1 , -1.1) | |:---------------------:|:----------------------:| | (90.8 , -45.9 , 5.0) | (89 , -40.4 , 15.5) | | (28.4 , -38.2 , 29.1) | (204.7 , 58.8 , -17.5) | ::: ## MSE,PSNR 有2張8位元灰階影像: 1. | 135 | 140 | 133 | |:---:|:---:|:---:| | 132 | 134 | 132 | | 136 | 136 | 150 | 2. | 138 | 146 | 143 | |:---:|:---:|:---:| | 140 | 135 | 137 | | 141 | 146 | 162 | 計算MSE(Mean Square Error)和PSNR(Peak signal-to-noise ratio) :::spoiler 點我顯示python程式碼 修改自chatgpt ```python= import math # 兩個圖像的像素值(以二維列表形式表示) image1 = [ [135, 140, 133], [132, 134, 132], [136, 136, 150] ] image2 = [ [138, 146, 143], [140, 135, 137], [141, 146, 162] ] # 計算均方誤差(MSE) def calculate_mse(image1, image2): mse = 0 total_pixels = 0 for i in range(len(image1)): for j in range(len(image1[0])): mse += (image1[i][j] - image2[i][j]) ** 2 total_pixels += 1 mse /= total_pixels return mse # 計算峰值信噪比(PSNR) def calculate_psnr(mse): MAX = 255 # 8位元圖像的最大像素值 psnr = round(10 * (math.log10(MAX**2) - math.log10(mse)),2) return psnr # 呼叫函數計算MSE mse_value = calculate_mse(image1, image2) # 計算PSNR psnr_value = calculate_psnr(mse_value) print("MSE:", mse_value) print("PSNR:", psnr_value) ``` ::: <br> :::success MSE <details> <summary>答</summary> MSE = 56 </details> 方法為: 計算每個像素點的差的平方的平均 `每個位置的點互減然後平方再全部總合算平均` $$ MSE = \frac{1}{N} \sum_{i=1}^{N} (I_{1i} - I_{2i})^2 $$ ::: :::success PSNR <details> <summary>答</summary> PSNR = 30.65 dB </details> 方法為: 10乘log(MAX平方除MSE) `MAX為像素最大值(8位元為255)` $$ PSNR = 10 \cdot \log_{10} \left( \frac{{\text{{MAX}}^2}}{{\text{{MSE}}}} \right) $$ ::: # 作業五 ## 直方圖等化 原圖為: | 0 | 0 | 4 | 5 | 4 | 2 | |:---:|:---:|:---:|:---:|:---:|:---:| | 0 | 2 | 0 | 4 | 5 | 1 | | 0 | 1 | 1 | 4 | 5 | 0 | | 0 | 5 | 4 | 6 | 6 | 0 | | 0 | 6 | 6 | 5 | 6 | 0 | | 5 | 6 | 5 | 4 | 5 | 4 | 依照原圖畫出表格: $r_k$=灰度級別 $n_k$=出現幾次 $P_r$($r_k$)=該像素占比(nk除總像素量) $s_k$=等化後的灰度級別(計算方式為0到$r_k$的$P_r$累積乘上最大灰度) | $r_k$ | $n_k$ | $P_r$($r_k$) | $s_k$ 計算 | $s_k$結果(四捨五入) | | ----- |:-----:|:---------------:|:---------------------------------:|:-------------------:| | 0 | 10 | $\frac{10}{36}$ | $\frac{10}{36}\times6\approx1.67$ | 2 | | 1 | 3 | $\frac{3}{36}$ | $\frac{13}{36}\times6\approx2.17$ | 2 | | 2 | 2 | $\frac{2}{36}$ | $\frac{15}{36}\times6\approx2.5$ | 3 | | 4 | 7 | $\frac{7}{36}$ | $\frac{22}{36}\times6\approx3.67$ | 4 | | 5 | 8 | $\frac{8}{36}$ | $\frac{30}{36}\times6\approx5$ | 5 | | 6 | 6 | $\frac{6}{36}$ | $\frac{36}{36}\times6\approx6$ | 6 | 在將圖片依照$s_k$結果改掉 :::spoiler 答 | 2 | 2 | 4 | 5 | 4 | 3 | |:---:|:---:|:---:|:---:|:---:|:---:| | 2 | 3 | 2 | 4 | 5 | 2 | | 2 | 2 | 2 | 4 | 5 | 2 | | 2 | 5 | 4 | 6 | 6 | 2 | | 2 | 6 | 6 | 5 | 6 | 2 | | 5 | 6 | 5 | 4 | 5 | 4 | ::: ## 空間上的冗餘 指的是圖像中的像素值或結構中存在重複、不必要的信息。 # 作業六 ## 視訊編碼流程 **有錯 懶得改** 捕捉 --> 預處理 --> 分幀 --> 移除冗餘資訊 --> 壓縮 --> 建立預測 --> 編碼 --> 壓縮位元流 --> 儲存或傳輸 --> 解碼和顯示 ## 區塊比對搜尋範圍方式 ![image.png](https://hackmd.io/_uploads/B1LNSPwmp.png) [圖取自台師大機構典藏系統](http://rportal.lib.ntnu.edu.tw:8080/server/api/core/bitstreams/272c8606-e420-4994-8482-1c0dbb9998bd/content) ## 全面搜尋演算法(Full Search Alogorithm)優缺點 優點: - 確保找到最優解 - 簡單易懂 - 通用性強 缺點: - 計算複雜度高 - 不適合大規模 ## 大部分關於減少搜尋點數的快速演算法,都是依據哪些重要的假設條件所設計? 空間相關性、低運動量、均勻性、局部性 ## 三步搜尋演算法(Three-Step Search Alogorithm:TSS)的步驟? ![image.png](https://hackmd.io/_uploads/ryO5uwP7a.png) [圖取自國立陽明交通大學機構典藏](https://ir.nctu.edu.tw/bitstream/11536/68124/1/251601.pdf) 1. 以原點、和最外圍8點為搜尋點,找區域最佳點。 2. 第一步找到的區域最佳點為中心,縮小搜尋範圍,並新增8個點,找區域最佳點。 3. 第二步找到的區域最佳點為中心,縮小搜尋範圍,並新增8個點,找區域最佳點,此點為全域最佳點。 # 版本歷史紀錄 | 日期 | 版次 | 修改原因 | 備註 | |:----------:|:----:|:--------:|:----:| | 2023/11/07 | 1.0 | 初版完成 | | | | | | |