openCV study-Module1_图像处理基础

REF:https://docs.opencv.org/3.3.0/d6/d00/tutorial_py_root.html

https://github.com/makelove/OpenCV-Python-Tutorial

 

https://github.com/HLearning/OpenCV-Python-Tutorials

颜色代码:https://www.sioe.cn/yingyong/yanse-rgb-16/

白色255,黑色0  BGR ,HSV https://blog.csdn.net/coldwindha/article/details/82080176

test picture source: https://github.com/saeedmehrang/OpenCVforPython/tree/master/images_to_test_scripts

  • installation:
    1. 按装 ANACONDA

             必须的库--             openCV ,nump, matplotlib

  • 查看函数帮助。spyider中 help (原库名.函数名) 比如 help (cv2.imgread)

lession.


Section 1, introduction: -----

1. openCV :学习图片的读取,保存,灰度

2. matplotlib 绘图函数(类似于matlab plot) 很强大!

3. 视频操作

4. 绘制几何图形

5. 鼠标点击事件捕捉

6. RGB调试版

  • 按装pygame
  1. 在开始菜单找到Anaconda下面的Anaconda Prompt,点击运行之;

    在Anaconda Prompt里面输入命令 pip install pygame,回车,电脑就开始自动下载和安装pygame库。

  2. Sesson 2--


    Core Operations

    In this section you will learn basic operations on image like pixel editing, geometric transformations, code optimization, some mathematical tools etc.

CV_Lesson7_图片像素操作

CV_Lesson8_图片像素填充padding

CV_Lesson9_图像的数学运算_加减等等

CV_Lesson10_图像的位操作.ipynb

数学运算:与,或,取反 etc.

CV_Lesson11_计算cost估算,算法性能评估函数.ipynb


3 class 3-- Processing in OpenCV

CV_Lesson12图片颜色滤波,提取_视频中追踪蓝色物体

CV_Lesson13_几何变换.py( 投影,仿射,平移,旋转) !!!

CV_Lesson14_图像阈值 !!!待完成: 理解How Otsu's Binarization Works? )图像二值化分割阈值 ; 高斯核

均值滤波:averaging filter 

在每个像素上进行这个操作。(边缘用padding), 求出平均值,然后替换掉原像素值。--使图片顺化,但是会模糊一些细节,比如脸上痣就没了:( 

----一般分类法。

--1.图片灰度化, 2-和阈值比较,超过或小于的像素赋值为0/或max

    threshold(src, thresh, maxval, type[, dst]) -> retval, dst

enum cv::ThresholdTypes


CV_Lesson15_图像滤波方法: image smoothing平衡. (滤波,模糊)! !

CV_Lesson16_形态学转换_图像腐蚀_膨胀去燥.py

CV_Lesson17_得到操作kernel_结构化元素.py


CV_Lesson18_图像梯度-高阶滤波.py

图像里面low pass filter -使图片模糊, high pass filter- 过滤出来edge.--就是对像素求导

像素求导的物理意义:

图像梯度公式如下: 
gradf(x,y) = dx i + dy j; 
dx(i,j) = I(i+1,j) - I(i,j); // x方向偏导,近似为某行与其上一行的差值 
dy(i,j) = I(i,j+1) - I(i,j); // y方向偏导,近似为某列与其上一列的差值 
其中,I是图像像素的值(亮度值),(i,j)为像素的坐标。
为简单说明,上面只考虑了一个象素与它上一行/上一列的差值,实际运算时,一般考虑以它为中心的NxN的小区域,小区域中各点权重不同,通过卷积计算(离得越远的点,权重越小),从而计算它各个方向上的变化



CV_Lesson19_Canny 边缘检测.py 

https://www.cnblogs.com/techyan1990/p/7291771.html

五步--
1.平滑去燥
2.获得梯度值,梯度方向
3.梯度图map ,进行最大值抑制得到0-1 map
4.梯度图进行双阈值检测
5.输出edge map


CV_Lesson20_图像金字塔.py

高斯金字塔

拉普拉斯金字塔(TBD

全景图片拼接:http://pages.cs.wisc.edu/~csverma/CS766_09/ImageMosaic/imagemosaic.html  TBD !!!

 

CV_Lesson21-1_轮廓.py

理解什么是轮廓,如何找轮廓,如何画轮廓

图像阈值滤波或canny fliter 得到binary Img,  找到轮廓的所有坐标点

在原图中画出来。
简单的4个点实现有问题!--轮廓的数据类型!!!--

contours is a Python list of all the contours in the image. Each individual contour is a Numpy array of (x,y) coordinates of boundary points of the object.

CCV_Lesson21-2_轮廓-计算图像的重心,周长,轮廓多边形直线拟合.py

对矩的理解moments ----https://blog.csdn.net/mailzst1/article/details/86747477

不用可以强求理解,知道有这个东西,可以干什么就可以了。TBC!!!

可以画出图片的重心。

  • 多边形直线拟合--代码没报错,结果现实不OK,参考了其他的代码也不行..test ok, 问题在于图片imread,需要先读原图,在灰度,不要合并!,注意参数调整。 找轮廓的过程中,原图对象被函数已经替换。注意!

CV_Lesson21-3_轮廓-画凸起包络线.py  Convex Hull 

返回的对象是,包络点  LIST------ N个* (1*2) 的点坐标,

§ convexHull()

void cv::convexHull(InputArray points,
  OutputArray hull,
  bool clockwise = false,
  bool returnPoints = true 
 )  

Finds the convex hull of a point set.

The function cv::convexHull finds the convex hull of a 2D point set using the Sklansky's algorithm [156] that has O(N logN) complexity in the current implementation. See the OpenCV sample convexhull.cpp that demonstrates the usage of different function variants.

Parameters

pointsInput 2D point set, stored in std::vector or Mat.
hullOutput convex hull. It is either an integer vector of indices or vector of points. In the first case, the hull elements are 0-based indices of the convex hull points in the original array (since the set of convex hull points is a subset of the original point set). In the second case, hull elements are the convex hull points themselves.
clockwiseOrientation flag. If it is true, the output convex hull is oriented clockwise. Otherwise, it is oriented counter-clockwise. The assumed coordinate system has its X axis pointing to the right, and its Y axis pointing upwards.
returnPointsOperation flag. In case of a matrix, when the flag is true, the function returns convex hull points. Otherwise, it returns indices of the convex hull points. When the output array is std::vector, the flag is ignored, and the output depends on the type of the vector: std::vector<int> implies returnPoints=false, std::vector<Point> implies returnPoints=true.

CV_Lesson21-4_轮廓-bouldingbox矩形,圆形直线椭圆拟合.py    &  轮廓的性质.

 

直线拟合:

§ fitLine()

void cv::fitLine(InputArray points,
  OutputArray line,
  int distType,
  double param,
  double reps,
  double aeps 
 )  

Fits a line to a 2D or 3D point set.

The function fitLine fits a line to a 2D or 3D point set by minimizing ∑iρ(ri) where ri is a distance between the ith point, the line and ρ(r) is a distance function, one of the following:

The algorithm is based on the M-estimator ( http://en.wikipedia.org/wiki/M-estimator ) technique that iteratively fits the line using the weighted least-squares algorithm. After each iteration the weights wi are adjusted to be inversely proportional to ρ(ri) .

Parameters

pointsInput vector of 2D or 3D points, stored in std::vector<> or Mat.
lineOutput line parameters. In case of 2D fitting, it should be a vector of 4 elements (like Vec4f) - (vx, vy, x0, y0), where (vx, vy) is a normalized vector collinear to the line and (x0, y0) is a point on the line. In case of 3D fitting, it should be a vector of 6 elements (like Vec6f) - (vx, vy, vz, x0, y0, z0), where (vx, vy, vz) is a normalized vector collinear to the line and (x0, y0, z0) is a point on the line.
distTypeDistance used by the M-estimator, see cv::DistanceTypes
paramNumerical parameter ( C ) for some types of distances. If it is 0, an optimal value is chosen.
repsSufficient accuracy for the radius (distance between the coordinate origin and the line).
aepsSufficient accuracy for the angle. 0.01 would be a good default value for reps and aeps.

CV_Lesson21-5_凸包缺陷计算.py

Contours 的层次结构Hierarchy--了解即可。--说明了一副图中,出现多个轮廓的表示方法

 

轮廓这个章节总算学完了,很重要的一节, 车辆的检查,boundingbox, 都需要他。 

总结一下。 图像灰度后,过滤(CANNY filter or 一般滤波)得到0-1二值图-->运用算法得到轮廓!


CV_Lesson22-1_直方图.py

CV_Lesson22-2_绘制三色直方图.py

CV_Lesson22-3_直方图mask.py

 

(1)对比度:一副图像中,各种不同颜色最亮处和最暗处之间的差别,差别越大对比度越高,这个跟分辨率没有多少关系,只跟最暗和最亮有关系,对比度越高一个图像给人的感觉就越刺眼,更加鲜亮,突出;越低则给人感觉变化不明显,反差就越小。这个概念只是在给定的图像中,与图像中颜色亮度的变化有关。

(2)亮度:一副图像给人的一种直观感受,如果是灰度图像,则跟灰度值有关,灰度值越高则图像越亮。

(3)饱和度:彩色图像的概念,饱和度为0的话,图像表现为灰度图像;饱和度越高颜色表现出种类越多,颜色表现更丰富,反之亦然。

 

 

   直方图:定义如下,x轴表示像素值0-255, y 表示图片中对应像素值的个数。 --直方图可以看出色调的分布。-对比度等信息

histSize=BIN: openCV 中用histSize表示, 指,统计的像素区域。直方图X方向的宽度。比如20个pixle 一个单位。类似于分辨率。

range =统计范围,一般0-255

API:

1.获取直方图 cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]])

mask-可以图片的局部统计, channel=0,1,2表示BGR ,

 

 

histogram_sample.jpg

CV_Lesson22-4_直方图均衡_histogram equalization.py

histogram_equalization.png像均衡化,很有用,例如人脸识别别 在 练分类器训练前,所有图片 先 直方图均 化从而使它们 到相同的亮度条件

背后的数学原理:https://blog.csdn.net/superjunenaruto/article/details/52431941  TBC.!

大致概念就是用概率分布来实现的算法。

§ equalizeHist()

void cv::equalizeHist(InputArray src,
  OutputArray dst 
 )  

Equalizes the histogram of a grayscale image.

The function equalizes the histogram of the input image using the following algorithm:

  • Calculate the histogram H for src .
  • Normalize the histogram so that the sum of histogram bins is 255.
  • Compute the integral of the histogram:

     

    H′i=∑0≤j<iH(j)

  • Transform the image using H′ as a look-up table: dst(x,y)=H′(src(x,y))

The algorithm normalizes the brightness and increases the contrast of the image.

Parameters

srcSource 8-bit single channel image.
dstDestination image of the same size and type as src .

自适应均衡技术
CLAHE (Contrast Limited Adaptive Histogram Equalization)
前面用的都是全局的均衡,可能会丢失一些信息,比如雕像脸部信息都没了
这个时候如果把图片分块,分别做均衡,效果会好很多,同时把对比度高于阈值的,滤掉,
§ createCLAHE()
Ptr<CLAHE> cv::createCLAHE    (    double     clipLimit = 40.0,--对比度阈值,建议调整
Size     tileGridSize = Size(8, 8) 

CV_Lesson22-5_2D直方图.py

本节学习2D -2维 直方图,前面只有一维,只有一个像素点值得信息,
如果考虑Hue 色调和饱和度saturation , 就是2D histogram了
HSV 色彩空间--概念理解https://baike.baidu.com/item/HSV/547122?fr=aladdin

cv2.imshow 不再适用,注意,用matpltlib来显示二位的histogram


CV_Lesson22-6_直方图反向投影.py --TBC ??

https://www.cnblogs.com/ssyfj/p/9271327.html

反向投影查找原理:查找的方式就是不断的在输入图像中切割跟模板图像大小一致的图像块,并用直方图对比的方式与模板图像进行比较。

假设我们有一张100x100的输入图像,有一张10x10的模板图像,查找的过程是这样的:
(1)从输入图像的左上角(0,0)开始,切割一块(0,0)至(10,10)的临时图像;
(2)生成临时图像的直方图;
(3)用临时图像的直方图和模板图像的直方图对比,对比结果记为c;
(4)直方图对比结果c,就是结果图像(0,0)处的像素值;
(5)切割输入图像从(0,1)至(10,11)的临时图像,对比直方图,并记录到结果图像;
(6)重复(1)~(5)步直到输入图像的右下角。

3.反向投影的结果包含了:以每个输入图像像素点为起点的直方图对比结果。可以把它看成是一个二维的浮点型数组,二维矩阵,或者单通道的浮点型图像。

可以这样理解:对于calcBackProjectPatch,也就是是基于块的反向投影形式,利用直方图做匹配,类似于模板匹配,只不过这些模板转换为直方图,而原图中以某点为基准,抠出来作对比的部分也转换为直方图,两个直方图作匹配,匹配的结果作为此点的值。 结果会是一张灰度图


图像的傅里叶变换!
CV_Lesson23_1_图像转换transfromation.py

CV_Lesson23_2_图像转换transfromation_CV法.py

CV_Lesson23_3_图像转换transfromation_性能比较

CV_Lesson23_4_图像转换transfromation_拉普拉斯变换_sobel --理解HPF,LPF ,图像显示结果看不懂 TBC??

傅里叶变换,概念复习: 2D Discrete Fourier Transform (DFT)-- A fast algorithm called Fast Fourier Transform (FFT) is used for calculation of DFT.

You can consider an image as a signal which is sampled in two directions. So taking fourier transform in both X and Y directions gives you the frequency representation of image.

高频,低频信号类比--图像中, 像素值变换大的--边缘--对应高频, 不大的就是低频了。

numpy 和CV 都提供了,CV 快一些,numpy更好用好记。

 As usual, OpenCV functions cv2.dft() and cv2.idft() are faster than Numpy counterparts.
 But Numpy functions are more user-friendly.


CV_Lesson24_1_模板匹配_tempalte match.py

CV_Lesson24_2_模板匹配_tempalte match_muti.py

小tip: array A[ : : -1]   ,  1*2 数组的第一第二个元素位置互换

概念就是,用一个模板图像,size为W*H, 和源图像w*h中对应的size块,一个像素为一个步长,逐个滑动,(卷积)通过特定的距离计算公式--匹配mode ,输出一个w-W+1,h-H+1的图像, 像素值,对应的就是卷积结果。 比如最接近的像素-->0, 通过min max函数,找到这个像素,定位,就找到了这个模板在图像中的位置。

想到了一个scal放大缩小的问题。? how解决?--发现无法匹配了!

逐像素比较,开销很大。时间长。如何解决?

§ matchTemplate()

void cv::matchTemplate(InputArray image,
  InputArray templ,
  OutputArray result,
  int method,
  InputArray mask = noArray() 
 )  

Compares a template against overlapped image regions.

The function slides through image , compares the overlapped patches of size w×h against templ using the specified method and stores the comparison results in result . Here are the formulae for the available comparison methods ( I denotes image, T template, R result ). The summation is done over template and/or the image patch: x′=0...w−1,y′=0...h−1

After the function finishes the comparison, the best matches can be found as global minimums (when TM_SQDIFF was used) or maximums (when TM_CCORR or TM_CCOEFF was used) using the minMaxLoc function. In case of a color image, template summation in the numerator and each sum in the denominator is done over all of the channels and separate mean values are used for each channel. That is, the function can take a color template and a color image. The result will still be a single-channel image, which is easier to analyze.

Parameters

imageImage where the search is running. It must be 8-bit or 32-bit floating-point.
templSearched template. It must be not greater than the source image and have the same data type.
resultMap of comparison results. It must be single-channel 32-bit floating-point. If image is W×H and templ is w×h , then result is (W−w+1)×(H−h+1) .
methodParameter specifying the comparison method, see cv::TemplateMatchModes
maskMask of searched template. It must have the same datatype and size with templ. It is not set by default. Currently, only the TM_SQDIFF and TM_CCORR_NORMED methods are supported.

   


CV_Lesson25_1_Hough transformation_直线检测.py

霍夫变换--图片中散点找直线(及时不连续也OK)

原理,一条直线在直角坐标系下可以用y=kx+b表示,为了计算方便,我们将参数空间的坐标表示为极坐标下的γ和θ。因为同一条直线上的点对应的(γ,θ)是相同的,因此可以先将图片进行边缘检测,然后对图像上每一个非零像素点,在参数坐标下变换为一条直线,那么在直角坐标下属于同一条直线的点便在参数空间形成多条直线并内交于一点。因此可用该原理进行直线检测。

Hough变换的原理是将特定图形上的点变换到一组参数空间上,根据参数空间点的累计结果找到一个极大值对应的解,那么这个解就对应着要寻找的几何形状的参数(比如说直线,那么就会得到直线的斜率k与常熟b,圆就会得到圆心与半径等等)。

关于hough变换,核心以及难点就是关于就是有原始空间到参数空间的变换上。以直线检测为例,假设有一条直线L,原点到该直线的垂直距离为p,垂线与x轴夹角为θ ,那么这条直线是唯一的,且直线的方程为 ρ=xcosθ+ysinθ 

要搞清楚的是,极坐标上每一个点对(ρ,θ) 在空间坐标上都是对应一条直线的

(0-180),(-0,-180)

So if the line is passing below the origin, it will have a positive rho and an angle less than 180. If it is going above the origin, instead of taking an angle greater than 180, the angle is taken less than 180, and rho is taken negative. Any vertical line will have 0 degree and horizontal lines will have 90 degree.

一个hough变换在算法设计上就可以如下步骤: --投票机制!!!
(1)将参数空间(ρ,θ) 量化,赋初值一个二维矩阵M,M(ρ,θ) 就是一个累加器了。 
(2)然后对图像边界上的每一个点进行变换,变换到属于哪一组(ρ,θ) ,就把该组(ρ,θ) 对应的累加器数加1,这里的需要变换的点就是上面说的经过边缘提取以后的图像了。 
(3)当所有点处理完成后,就来分析得到的M(ρ,θ) ,设置一个阈值T,认为当M(ρ,θ)>T ,就认为存在一条有意义的直线存在。而对应的M(ρ,θ) 就是这组直线的参数,至于T是多少,自己去式,试的比较合适为止。 
(4)有了M(ρ,θ) 和点(x,y)计算出来这个直线就ok了。

Consider a 100x100 image with a horizontal line at the middle. Take the first point of the line. You know its (x,y) values. Now in the line equation, put the values θ=0,1,2,....,180 and check the ρ you get. For every (ρ,θ) pair, you increment value by one in our accumulator in its corresponding (ρ,θ) cells. So now in accumulator, the cell (50,90) = 1 along with some other cells.

已知一个点坐标,theta  赋值0,1,2.。。, 得到对应的rho, 放到统计器中,

对其它的点做同样操作, --某一个theta,rho出现次数最多--就是共线的 直线

Now take the second point on the line. Do the same as above. Increment the values in the cells corresponding to (rho, theta) you got. This time, the cell (50,90) = 2. What you actually do is voting the (ρ,θ) values. You continue this process for every point on the line. At each point, the cell (50,90) will be incremented or voted up, while other cells may or may not be voted up. This way, at the end, the cell (50,90) will have maximum votes. So if you search the accumulator for maximum votes, you get the value (50,90) which says, there is a line in this image at a distance 50 from the origin and at angle 90 degrees. It is well shown in the below animation (Image Courtesy: Amos Storkey )

houghlinesdemo.gif

 

cv2.HoughLines()cv2.HoughLinesP()

 

霍夫变换-找圆形

CV_Lesson25_2_Hough transformation_圆形检测.py

应用: DMS人眼检测。

原理同直线:

其实检测圆形和检测直线的原理差别不大,只不过直线是在二维空间,因为y=kx+b,只有k和b两个自由度。而圆形的一般性方程表示为(x-a)²+(y-b)²=r²。那么就有三个自由度圆心坐标a,b,和半径r。这就意味着需要更多的计算量,而OpenCV中提供的cvHoughCircle()函数里面可以设定半径r的取值范围,相当于有一个先验设定,在每一个r来说,在二维空间内寻找a和b就可以了,能够减少计算量。

具体步骤如下:

3.同霍夫变换检测直线一样,将圆形的一般性方程换一种方式表示,进行坐标变换。由x-y坐标系转换到a-b坐标系。写成如下形式(a-x)²+(b-y)²=r²。那么x-y坐标系中圆形边界上的一点对应到a-b坐标系中即为一个圆。

4.那x-y坐标系中一个圆形边界上有很多个点,对应到a-b坐标系中就会有很多个圆。由于原图像中这些点都在同一个圆形上,那么转换后a,b必定也满足a-b坐标系下的所有圆形的方程式。直观表现为这许多点对应的圆都会相交于一个点,那么这个交点就可能是圆心(a, b)。

5.统计局部交点处圆的个数,取每一个局部最大值,就可以获得原图像中对应的圆形的圆心坐标(a,b)。一旦在某一个r下面检测到圆,那么r的值也就随之确定。

以下面的图片为例,调用OpenCV中的cvHoughCircles()进行圆形的检测,

              


CV_Lesson26_图像分割_分水岭Watershed算法.py TBC,不理解...

https://www.cnblogs.com/ssyfj/p/9278815.html


CV_Lesson27_提取前景色.py TBC,不理解...

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值