# 2023 NCKU 影像處理 HW1
contributed by [tintinjian12999](https://github.com/tintinjian12999)
L76124157 簡瑋廷
[程式碼在這裡](https://github.com/tintinjian12999/digital_image_processing/tree/main)
## Introduction
為了增加運算時的效能,這裡透過 c++ 呼叫 opencv 做影像處理的函數部份,並編譯成動態連結檔。 再透過 python 呼叫它並建立 GUI 執行。
用以下指令編譯成動態連結檔
```
g++ -shared -fPIC -o main.so main.cpp $(pkg-config --cflags --libs opencv4)
```
並用以下指令執行 python 程式
```
python3 image_processing.py
```
## C++
```cpp
//main.cpp
void average_filter_cpp(const uchar* inputImage, uchar* outputImage, int rows, int cols) {
Mat inputMat(rows, cols, CV_8UC1, const_cast<uchar*>(inputImage));
Mat outputMat(rows, cols, CV_8UC1, outputImage);
blur(inputMat, outputMat,Size(3, 3));
outputMat.copyTo(cv::Mat(rows, cols, CV_8UC1, outputImage));
}
```
主要是透過 c++ 執行函數的功能並輸出處理後的圖片,整個 c++ 檔打包成 `extern "C"` 的形式。
## python
```python
#image_processing.py
image_processing_lib = ctypes.CDLL('./main.so') # For Linux
image_processing_lib.average_filter_cpp.argtypes = [POINTER(c_ubyte),
POINTER(c_ubyte),
c_int,
c_int]
image_processing_lib.average_filter_cpp.restype = None
image_processing_lib.median_filter_cpp.argtypes = [POINTER(c_ubyte),
POINTER(c_ubyte),
c_int,
c_int]
image_processing_lib.median_filter_cpp.restype = None
```
用來引入 c++ 的動態連接檔並定義函數的傳入傳出形式。
```python
def smooth_filter(self):
method_set = ['average', 'median', 'fourier']
if self.image is not None:
for i, method in enumerate(['average', 'median', 'fourier']):
label = Label(self.master, text=f"{method.capitalize()} Filter")
col_num = 0 if i in [1] else 3
label.grid(row=min(2, i + 1), column=col_num, columnspan=3)
self.processed_labels[method] = label
image_ptr = self.image.ctypes.data_as(POINTER(c_ubyte))
output_median = np.ones_like(self.image) * 255
output_median_ptr = output_median.ctypes.data_as(POINTER(c_ubyte))
output_average = np.ones_like(self.image) * 255
output_average_ptr = output_average.ctypes.data_as(POINTER(c_ubyte))
output_fourier = np.ones_like(self.image) * 255
output_fourier_ptr = output_fourier.ctypes.data_as(POINTER(c_ubyte))
image_processing_lib.average_filter_cpp(image_ptr, output_average_ptr, self.image.shape[0],
self.image.shape[1])
image_processing_lib.median_filter_cpp(image_ptr, output_median_ptr, self.image.shape[0],
self.image.shape[1])
image_processing_lib.fourier_filter_cpp(image_ptr, output_fourier_ptr, self.image.shape[0],
self.image.shape[1])
self.processed_images['median'] = output_median
self.processed_images['fourier'] = output_fourier
self.processed_images['average'] = output_average
self.show_processed_images(method_set)
```
在下方定義 GUI 的類別中呼叫編譯後的 c++ 函數執行並轉換成 opencv 的資料型態進行圖片輸出。
## 執行結果
### 界面

在按下 open image 並載入圖片後會顯示原始圖像。

### Smooth filter
按下 Smooth Filter 後會出現以下結果

### Sharp
重新讀取為 Figure_2 並按下 Sharp 會出現以下結果

### Gaussian blur
按下 Gaussian blur 會出現以下結果

### Gaussian lowpass
按下 Gaussian lowpass 會出現以下結果
