# 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 的資料型態進行圖片輸出。 ## 執行結果 ### 界面 ![圖片](https://hackmd.io/_uploads/BJfTFV6Ha.png) 在按下 open image 並載入圖片後會顯示原始圖像。 ![圖片](https://hackmd.io/_uploads/SyZxc4pra.png) ### Smooth filter 按下 Smooth Filter 後會出現以下結果 ![圖片](https://hackmd.io/_uploads/BJ5M9VpH6.png) ### Sharp 重新讀取為 Figure_2 並按下 Sharp 會出現以下結果 ![2023-12-06 08-03-44 的螢幕擷圖](https://hackmd.io/_uploads/rJf6c4ar6.png) ### Gaussian blur 按下 Gaussian blur 會出現以下結果 ![2023-12-06 08-06-13 的螢幕擷圖](https://hackmd.io/_uploads/Hk7boVpB6.png) ### Gaussian lowpass 按下 Gaussian lowpass 會出現以下結果 ![2023-12-06 08-06-53 的螢幕擷圖](https://hackmd.io/_uploads/ryyEsV6HT.png)