官方微博:AI有道
之前,我發文推薦過一份影象處理入門 100 題,主要針對影象處理的一些基本操作,非常適合入門!
但是,這份資源教程是由日本人寫的,日文版,讀起來非常不方便。好訊息,最近我在逛 GitHub 的時候,發現有人將這份教程翻譯成了中文版。該專案包含了 CV 領域,OpenCV 影象處理入門 100 題例項解析,並配備完整的 Pyhon 程式碼。
首先,放上原版日文地址:
https://github.com/yoyoyo-yo/Gasyori100knock
對應的中文版翻譯地址:
https://github.com/gzr2017/ImageProcessing100Wen
Tutorial
這部分的極簡教程主要是介紹影象處理開源庫 OpenCV 的安裝,讀取、顯示影象、操作畫素等一些基本操作。分為 Python 版和 C++ 兩種形式。
作者推薦了 OpenCV 的極簡安裝方法:
1. 安裝 MiniConda
地址:https://conda.io/miniconda.html
2. 建立虛擬環境並啟用
$ conda create python = 3.6 - n gasyori 100
$ source actiavte gasyori 100
3. 安裝包
$ pip install -r requirement.txt
其中,requirement.txt 檔案在專案根目錄下,下載至命令列所在目錄直接執行上述命令即可。
該專案總共包含了 100 道影象處理入門題,下面分別來看一下!
問題 1-10
這部分提供了 Python 和 C++ 兩種形式。例如看中值濾波演算法。
Python:
import cv2
import numpy as np
# Read image
img = cv2.imread("imori_noise.jpg")
H, W, C = img.shape
# Gaussian Filter
K_size = 3
sigma = 1.3
## Zero padding
pad = K_size // 2
out = np.zeros((H + pad*2, W + pad*2, C), dtype=np.float)
out[pad:pad+H, pad:pad+W] = img.copy().astype(np.float)
## Kernel
K = np.zeros((K_size, K_size), dtype=np.float)
for x in range(-pad, -pad+K_size):
for y in range(-pad, -pad+K_size):
K[y+pad, x+pad] = np.exp( -(x**2 + y**2) / (2* (sigma**2)))
K /= (sigma * np.sqrt(2 * np.pi))
K /= K.sum()
tmp = out.copy()
for y in range(H):
for x in range(W):
for c in range(C):
out[pad+y, pad+x, c] = np.sum(K * tmp[y:y+K_size, x:x+K_size, c])
out = out[pad:pad+H, pad:pad+W].astype(np.uint8)
# Save result
cv2.imwrite("out.jpg", out)
cv2.imshow("result", out)
cv2.waitKey(0)
cv2.destroyAllWindows()
C++ 版:
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <math.h>
// gaussian filter
cv::Mat gaussian_filter(cv::Mat img, double sigma, int kernel_size){
int height = img.rows;
int width = img.cols;
int channel = img.channels();
// prepare output
cv::Mat out = cv::Mat::zeros(height, width, CV_8UC3);
// prepare kernel
int pad = floor(kernel_size / 2);
int _x = 0, _y = 0;
double kernel_sum = 0;
// get gaussian kernel
float kernel[kernel_size][kernel_size];
for (int y = 0; y < kernel_size; y++){
for (int x = 0; x < kernel_size; x++){
_y = y - pad;
_x = x - pad;
kernel[y][x] = 1 / (2 * M_PI * sigma * sigma) * exp( - (_x * _x + _y * _y) / (2 * sigma * sigma));
kernel_sum += kernel[y][x];
}
}
for (int y = 0; y < kernel_size; y++){
for (int x = 0; x < kernel_size; x++){
kernel[y][x] /= kernel_sum;
}
}
// filtering
double v = 0;
for (int y = 0; y < height; y++){
for (int x = 0; x < width; x++){
for (int c = 0; c < channel; c++){
v = 0;
for (int dy = -pad; dy < pad + 1; dy++){
for (int dx = -pad; dx < pad + 1; dx++){
if (((x + dx) >= 0) && ((y + dy) >= 0)){
v += (double)img.at<cv::Vec3b>(y + dy, x + dx)[c] * kernel[dy + pad][dx + pad];
}
}
}
out.at<cv::Vec3b>(y, x)[c] = v;
}
}
}
return out;
}
int main(int argc, const char* argv[]){
// read image
cv::Mat img = cv::imread("imori_noise.jpg", cv::IMREAD_COLOR);
// gaussian filter
cv::Mat out = gaussian_filter(img, 1.3, 3);
//cv::imwrite("out.jpg", out);
cv::imshow("answer", out);
cv::waitKey(0);
cv::destroyAllWindows();
return 0;
}
問題 11-20
問題 21-30
問題 31-40
問題 41-50
問題 51-60
問題 61-70
問題 71-80
問題 81-90
問題 91-100
該專案最大的特色就是 100 題循序漸進,基本涵蓋了 OpenCV 的關鍵知識點。如果你正在入門 CV,正在學習 OpenCV,那麼這個專案將會是一個不錯的從入門到進階的教程。上手程式碼,親自跑一跑結果,希望對大家有所幫助!