工具: MATLAB;
动机:使用 MATLAB toolbox 程序设计相对简单,通过初步学习一些图像处理的常见技术,帮助建立这方面的技能体系;
面向对象:有过经验,但是一头雾水的我。
1 图像、视频文件读取
clear all; close all; clc;% Read an imageA = imread('lena.jpg');% Display the read imagefigure, imshow(A);% Print height, width and number of channels of the read imageheight = size(A, 1);width = size(A, 2);number_of_channels = size(A, 3);% Resize the image to 2x and displayB = imresize(A, 2.0);figure, imshow(B);% Rotate the image 逆时针旋转C = imrotate(A, 90);figure, imshow(C);
关键点:imread,figure(imshow),size获取高度,宽度,图像通道数的参数,图像缩放,旋转。
clear all; close all; clc;% Read an imageA = imread('lena.jpg');% Translate the imageA_trans = imtranslate(A, [5 15]);% Write the transformed image to diskimwrite(A_trans, 'newlena.jpg');figure,imshow(A_trans);
关键:imwrite及其调用前做的工作。
1-1 视频读取(选看)
clear all; close all; clc;% Initialize an object for reading video videoObj = vision.VideoFileReader('video1.mp4', 'ImageColorSpace', 'RGB'); % Get video frame size and frame rate S = info(videoObj);width = S.VideoSize(1);height = S.VideoSize(end);frame_rate = S.VideoFrameRate;% Get individual video framesimage_data = step(videoObj);% Run the loop until all frames have been displayedwhile ~isDone(videoObj) % Display video frame one by one imshow(image_data); image_data = step(videoObj);end% Release the object for reading videorelease(videoObj);
关键:step,其流程reader读取生成对象,得到信息,逐帧显示 , PS:视频教程中有另外一种实现。
3 图像格式
3.1 RGB、灰度图片
clear all; close all; clc;% Read a RGB imageA = imread('lena.jpg');% Verify number of channelsnumber_of_channels = size(A, 3)% Convert RGB image to GrayscaleA_gray = rgb2gray(A);number_of_channels2 = size(A_gray, 3)figure, subplot(1, 2, 1), imshow(A), title('Input RGB image');subplot(1, 2, 2), imshow(A_gray), title('Converted Grayscale image');
关键:灰度图像颜色通道位1,rgb图像颜色通道数是3,subplot 显示多个图像,便于查看。
clear all; close all; clc;% Read a RGB imageA = imread('lena.jpg');% Extract individual R, G & B channels from RGB imageR = A(:, :, 1);G = A(:, :, 2);B = A(:, :, 3);% Convert RGB image to HSV color spaceA_hsv = rgb2hsv(A);% Extract individual H, S & V channels from HSV imageH = A_hsv(:, :, 1);S = A_hsv(:, :, 2);V = A_hsv(:, :, 3);% Display the read RGB image and HSV converted imagefigure, subplot(1, 2, 1), imshow(A), title('Read RGB image');subplot(1, 2, 2), imshow(A_hsv), title('Converted HSV image');% Displaying individual image channels.figure, subplot(1, 3, 1), imshow(S), title('Saturation channel');subplot(1, 3, 2), imshow(H), title('Hue channel');subplot(1, 3, 3), imshow(V), title('Value channel');
关键:R、G、B、H、S、V 都是提取空间域(矩阵表示)的信息,位图片大小,RGB、HSV格式都是3个颜色通道,前者unit8,后者double格式。PS:HSV 有用的是V(当前)。
4 直方图及其均衡化
直方图以前都是空间域上对像素操作,直方图则是借助频率来获取图像的统计信息 imhist。
clear all; close all; clc;% Read an imageA = imread('lena.jpg');B = imread('lena.jpg');% Convert the read image to single-channelA = rgb2gray(A);% Plot and display the histogram if A is a single channel image with% default number of binsfigure, subplot(1,3,1),imhist(A), title('Histogram of read image'); subplot(1,3,2),imshow(A),title('Grayscale image'); subplot(1,3,3),imshow(B),title('RGB image');
直方图:左边暗,右边亮,不同亮度出现的频率,注意直方图应该表示一个颜色通道的统计信息,不要把RGB、HSV等格式图片多个通道的格式混合起来,这样是得不到可分析的信息的,RGB如下直方图生成方式如下:
clear all; close all; clc;% Read an imageA = imread('lena.jpg');% Plot and display the histogram if A is a 3 channel image with% default number of binsfigure, imhist(A(:, :, 1)), title('Histogram of 1st channel of read image');figure, imhist(A(:, :, 2)), title('Histogram of 2nd channel of read image');figure, imhist(A(:, :, 3)), title('Histogram of 3rd channel of read image');
5 直方图均衡化
亮度分布集中在左边图片太暗,集中在右边图片太亮,直方图均衡化就是让图像的不同像素点亮度均匀话,对灰度图片和其他格式图片有不同的做法
clear all; close all; clc;% Read an imageA = imread('test1.jpg');% Convert the image to single channel imageA = rgb2gray(A);% Equalize the histogram of read single channel imageA_histeq = histeq(A);% Display original and equalized images side by side with their respective% histogram plotsfigure, subplot(2, 2, 1), imshow(A), title('Original Image');subplot(2, 2, 2), imshow(A_histeq), title('Equalized Image');subplot(2, 2, 3), imhist(A), title('Histogram of Original Image');subplot(2, 2, 4), imhist(A_histeq), title('Histogram of Equalized Image');
关键:imhist,histeq,
clear all; close all; clc;% Read a RGB imageA = imread('test1.jpg');% Convert the RGB image into HSV imageA_hsv = rgb2hsv(A);% Perform histogram equalization of V-channel in HSV image which is the 3rd% channelA_hsv(:, :, 3) = histeq(A_hsv(:, :, 3));% Convert back equalized HSV image into RGB imageA_histeq = hsv2rgb(A_hsv);% Display original and equalized RGB images side by sidefigure, subplot(1, 2, 1), imshow(A), title('Original RGB image');subplot(1, 2, 2), imshow(A_histeq), title('Equalized RGB image');
关键:histeq(A(:,:,3) ,A是hsv格式,流程:RGB图片转化为HSV 图片,然后对HSV图片的V进行均衡化,均衡化后重新转化为RGB图片。
6 图像平滑化(image smoothing)
释义:消除、弱化、压缩图像的噪声、边缘、细节、突变。可以在空间域(滤波)和频域上进行。fspecial、infilter
空间域: 生成一个任何大小的矩阵,用该矩阵对图像某个像素及其周围像素进行集体操作后代替原像素。根据将像素值设置为不同的值类型,可以分为:最小化,最大化,均值,加权均值操作。
空间滤波示例,流程:生成灰度图像,生成滤波器,应用滤波,执行滤波操作,PS:中值滤波过程不一样。
clear all; close all; clc;% Read an input imageA = imread('test1.jpg');% Conversion to single channel imageA = rgb2gray(A);% Generate Average filteraverage_h = fspecial('average', [9 9]);% Generate Gaussian filtergaussian_h = fspecial('gaussian', [13 13]);% Filter input image using average filterB_average = imfilter(A, average_h);% Filter input image using Gaussian filterB_gaussian = imfilter(A, gaussian_h);% Filter input image using median filterB_median = medfilt2(A, [5 5]);% Display input and filtered images side by sidefigure, subplot(2, 2, 1), imshow(A), title('Original input image');subplot(2, 2, 2), imshow(B_average), title('Image filtered using Averaging filter');subplot(2, 2, 3), imshow(B_gaussian), title('Image filtered using Gaussian filter');subplot(2, 2, 4), imshow(B_median), title('Image filtered using Median filter');
均值滤波是最简单的空间滤波,特点:1、非加权;2、适用于去噪声,但会使图片模糊;3、突出总体细节
6.2 中值滤波(加权平滑滤波器)
pixel 有不同权值的滤波器,特点:越靠近中心的像素越重要;与非权值的滤波操作(均值滤波)相比,更好的模糊化,滤波器构造如下图所示。
补充一个导向滤波的例子,这么做的目的是保留图像的边缘。
clear all; close all; clc;% Read an imageA = imread('test1.jpg');% Filter the image using guided filterA_guided_filtered = imguidedfilter(A);% Display original and processed image side-by-sideimshowpair(A, A_guided_filtered, 'montage');
7 边缘检测
边缘是重要的图像强度局部变化像素点的集合。边缘方向:垂直于图像强度最大强度变化的方向。
思路:空间域上对 x, y 求导,大于特定的值就是边缘,不同的算子生成方式有不同的近似求导方案。
clear all; close all; clc;% Read an imageA = imread('test1.jpg');% Convert the image to single-channel intensity image if the read image% is RGB (3-channel)A_gray = rgb2gray(A);% Method for Sobel edge detectionBW_sobel = edge(A_gray, 'sobel');% Method for Prewitt edge detectionBW_prewitt = edge(A_gray, 'prewitt');% Method of Canny edge detectionBW_canny = edge(A_gray, 'canny');% Display the images togetherfigure, subplot(2, 2, 1), imshow(A_gray), title('Original');subplot(2, 2, 2), imshow(BW_sobel), title('Sobel');subplot(2, 2, 3), imshow(BW_prewitt), title('Prewitt');subplot(2, 2, 4), imshow(BW_canny), title('Canny');
8 二值图像(im2bw)
图像只有两个值0,1,根据直方图左边暗,右边亮,左边取0(黑),右边取1(白),二值图像是根据直方图,大于某个值则设置为1(白色),二值图像生成的关键就是这个阈值的选择,否则二值图像生成的背景、人物、物体会杂糅在一起,没有办法继续处理。
流程:灰度 - double - im2bw,第2个参数要 ∈[0,1] ,阈值除以 255 带入 。 PS: otsu 算法已经集成在matlab 工具箱中了
clear all;close all;clc; % Read an input imageA = imread('test1.jpg');% Convert the image to single-channel grayscale imageA_gray = rgb2gray(A);figure,imhist(A_gray),title('hist of A_grey');% Convert image to double i.e., [0,1]A_gray = im2double(A_gray);% Generate threhold value using Otsu's algorithmotsu_level = graythresh(A_gray);% Threshold image using Otsu's threshold and manually defined% threshold valuesB_otsu_thresh = im2bw(A_gray, otsu_level);B_thresh_50 = im2bw(A_gray, 50/255);B_thresh_100 = im2bw(A_gray, 100/255);B_thresh_150 = im2bw(A_gray, 150/255);B_thresh_200 = im2bw(A_gray, 200/255);% Display original and thresholded binary images side-by-sidefigure, subplot(2, 3, 1), imshow(A_gray), title('Original image');subplot(2, 3, 2), imshow(B_otsu_thresh), title('Binary image using Otsu threshold value');subplot(2, 3, 3), imshow(B_thresh_50), title('Binary image using threshold value = 50');subplot(2, 3, 4), imshow(B_thresh_100), title('Binary image using threshold value = 100');subplot(2, 3, 5), imshow(B_thresh_150), title('Binary image using threshold value = 150');subplot(2, 3, 6), imshow(B_thresh_200), title('Binary image using threshold value = 200');
9 图像降噪 ( fsepcial,imfilter)
噪声来源于 图像采集及转化、传输过程。
噪声分类: 高斯:正态分布;椒盐:一定概率分布的黑白像素点;冲击噪声:随机白点。
降噪手段:最简单的是均值滤波,但是会模糊整个图片,中值滤波:适用于椒盐噪声。
周期性的噪声多来自于电子电磁干扰,噪声在图像中的分布具有规律性(周期性),傅里叶域的频域技术咋消除周期性噪声是最有效的。带阻滤波:适合移除图片噪声及移除特定范围的频率。
clear all; close all; clc;% Read an input imageA = imread('test1.jpg');% Generate Gaussian and Average filtersh_gaussian = fspecial('gaussian');h_average = fspecial('average');% Filter input image using generated Gaussian and Average filtersB_gaussian = imfilter(A, h_gaussian);B_average = imfilter(A, h_average);% Filter input image using Median filter% Median filtering function takes as input grayscale imageA_gray = rgb2gray(A);B_median = medfilt2(A_gray);% Display original and filtered images side-by-side for comparing the% result of image de-noisingfigure, subplot(2, 2, 1), imshow(A), title('Original image with Salt & Pepper noise');subplot(2, 2, 2), imshow(B_gaussian), title('Input image filtered using Gaussian filter');subplot(2, 2, 3), imshow(B_average), title('Input image filtered using Average filter');subplot(2, 2, 4), imshow(B_median), title('Input image filtered using Median filter');
10 形态学
Erosion 腐蚀 :imerode 分离相连物体,去毛刺,让物体变小;Dilation 膨胀 imdilate,拼接物体,填表面小坑,物体变大。
close all; clear all; clc;% Read an input imageA = imread('binaryImg1.jpg');% Convert to single channelA = rgb2gray(A);% Generate structuring element for usese = strel('disk', 15); % Perform image erosionB_eroded = imerode(A, se);% Perform image dilationB_dilated = imdilate(A, se);% Display the images side-by-side for comparisonfigure, subplot(1, 3, 1), imshow(A), title('Original read image');subplot(1, 3, 2), imshow(B_eroded), title('Original image after Erosion');subplot(1, 3, 3), imshow(B_dilated), title('Original image after Dilation');
开运算:先腐蚀再膨胀,分离物体、去毛刺、去小点(物体点),去小部件,表面坑变小。
闭运算:先膨胀再腐蚀,表面坑被填,内部背景点消失,表面坑被填,毛刺不变。
clear all; close all; clc;% Read an input imageA = imread('binaryImg1.jpg');% Convert read image to single channel imageA = rgb2gray(A);% Generate structuring element for processingse = strel('disk', 15); % Perform image opening operationB_open = imopen(A, se);% Perform image closing operationB_close = imclose(A, se);% Display original and processed imagesfigure, subplot(1, 3, 1), imshow(A), title('Original image');subplot(1, 3, 2), imshow(B_open), title('Original image after Opening');subplot(1, 3, 3), imshow(B_close), title('Original image after Closing');
利用膨胀得到物体边缘
clear all; close all; clc;% Read an input imageA = imread('binaryImg1.jpg');% Convert the read image to single channel imageA = rgb2gray(A);% Generate structuring element for usese = strel('disk', 5); % Perform image dilation% To get the object boundary, subtract the original image from the dilated% version of the orginal imageB_dilated = imdilate(A, se);% Subtract the original image from dilated imageB_boundary = B_dilated - A;% Display images side by sidefigure, subplot(1, 3, 1), imshow(A), title('Original image');subplot(1, 3, 2), imshow(B_dilated), title('Original image after Dilation');subplot(1, 3, 3), imshow(B_boundary), title('Original image with highlighted binary object boundaries');
利用腐蚀得到物体边缘
clear all; close all; clc;% Read an input imageA = imread('binaryImg1.jpg');% Convert the read image to single channel imageA = rgb2gray(A);% Generate structuring element for usese = strel('disk', 5); % Perform image erosionB_eroded = imerode(A, se);% Subtract the eroded image from original imageB_boundary = A - B_eroded;% Display images side by sidefigure, subplot(1, 3, 1), imshow(A), title('Original image');subplot(1, 3, 2), imshow(B_eroded), title('Original image after Erosion');subplot(1, 3, 3), imshow(B_boundary), title('Original image with highlighted binary object boundaries');