<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 |
:::
## 空間上的冗餘
指的是圖像中的像素值或結構中存在重複、不必要的信息。
# 作業六
## 視訊編碼流程
**有錯 懶得改**
捕捉 --> 預處理 --> 分幀 --> 移除冗餘資訊 --> 壓縮 --> 建立預測 --> 編碼 --> 壓縮位元流 --> 儲存或傳輸 --> 解碼和顯示
## 區塊比對搜尋範圍方式

[圖取自台師大機構典藏系統](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)的步驟?

[圖取自國立陽明交通大學機構典藏](https://ir.nctu.edu.tw/bitstream/11536/68124/1/251601.pdf)
1. 以原點、和最外圍8點為搜尋點,找區域最佳點。
2. 第一步找到的區域最佳點為中心,縮小搜尋範圍,並新增8個點,找區域最佳點。
3. 第二步找到的區域最佳點為中心,縮小搜尋範圍,並新增8個點,找區域最佳點,此點為全域最佳點。
# 版本歷史紀錄
| 日期 | 版次 | 修改原因 | 備註 |
|:----------:|:----:|:--------:|:----:|
| 2023/11/07 | 1.0 | 初版完成 | |
| | | | |