之前,我发文推荐过一份图像处理入门 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,那么这个项目将会是一个不错的从入门到进阶的教程。上手代码,亲自跑一跑结果,希望对大家有所帮助!