1,不同色彩空间的转换

OpenCV中有数百种关于在不同色彩空间之间转换的方法。当前,在计算机视觉中有三种常用的色彩空间:灰度、BGR以及HSV(Hue,Saturation,Value)。

色彩空间

详情

灰度

通过去除彩色信息来将其转换成灰阶,灰度色彩空间对中间处理特别有效,比如人脸检测。

BGR

即蓝-绿-红色彩空间,每一个像素点都由一个三元数组来表示,分别代表蓝、绿、红三种颜色。网页开发者可能熟悉另一个与之相似的颜色空间: RGB,它们只是在颜色的顺序上不同。

HSV

H ( Hue)是色调,S ( Saturation) 是饱和度,V ( Value)表示黑暗的程度(或光谱另一端的明亮程度 )。

2,傅里叶变换

Joseph Fourier(约瑟夫·傅里叶)是一位18世纪的法国数学家,他认为一切都可以用波形来描述。简而言之:他观察到所有的波形都可以由一系列简单且频率不同的正弦曲线叠加得到。也就是说,人们所看到的波形都是由其他波形叠加而得到的。

图像的幅度谱是另–种图像,幅度谱图像呈现了原始图像在变化方面的一种表示:把一幅图像中最明亮的像素放到图像中央,然后逐渐变暗,在边缘上的像素最暗。这样可以发现图像中有多少亮的像素和暗的像素,以及它们分布的百分比。

2.1 高通滤波器

高通滤波器(HPF)是检测图像的某个区域,然后根据像素与周围像素的亮度差值来提升(boost)该像素的亮度的滤波器。
在计算完中央像素与周围邻近像素的亮度差值之和以后,如果亮度变化很大,中央像素的亮度会增加(反之则不会)。
换句话说,如果一个像素比它周围的像素更突出,就会提升它的亮度。

高通和低通滤波器都有一一个称为半径( radius)的属性,它决定了多大面积的邻近像素参与滤波运算。

是指一组权重的集合,它会应用在源图像的一个区域,并由此生成目标图像的一个像素。
比如,大小为7的核意味着每49 (7x7)个源图像的像素会产生目标图像的一个像素。
可把核看作一块覆盖在源图像上可移动的毛玻璃片,玻璃片覆盖区域的光线会按某种方式进行扩散混合后透过去。

import cv2
import numpy as np
from scipy import ndimage

#这些滤波器种所有值加起来为0
kernel_3x3 = np.array([[-1,-1,-1],
                        [-1,8,-1],
                        [-1,-1,-1]])

kernel_5x5 = np.array([[-1,-1,-1,-1,-1],
                        [-1,1,2,1,-1],
                        [-1,2,4,2,-1],
                        [-1,1,2,1,-1],
                        [-1,-1,-1,-1,-1]])
                        
img = cv2.imread('result.jpg',0)

k3 = ndimage.convolve(img,kernel_3x3)
k5 = ndimage.convolve(img,kernel_5x5)

blurred = cv2.GaussianBlur(img,(11,11),0)
g_hpf = img - blurred

cv2.imshow('3x3',k3)
cv2.imshow('5x5',k5)
cv2.imshow('g_hpg',g_hpf)
cv2.waitKey()
cv2.destroyAllWindows()

原图:

opencv 三维坐标系 opencv显示三维图像_opencv


运行结果:

opencv 三维坐标系 opencv显示三维图像_opencv 三维坐标系_02

2.2 低通滤波器

高通滤波器是根据像素与邻近像素的亮度差值来提升该像素的亮度。
低通滤波器(LowPass Filter, LPF)则是在像素与周围像素的亮度差值小于一个特定值时,平滑该像素的亮度。
它主要用于去噪和模糊化,比如说,高斯模糊是最常用的模糊滤波器(平滑滤波器)之一,它是一个削弱高频信号强度的低通滤波器。

2.7 Canny边缘检测

Canny边缘检测算法非常复杂,但也很有趣:它有5个步骤,
使用高斯滤波器对图像进行去噪计算梯度在边缘上使用非最大抑制(NMS)在检测到的边缘上使用双( double)阈值去除假阳性( false positive),最后还会分析所有的边缘及其之间的连接,以保留真正的边缘并消除不明显的边缘

import cv2
import numpy as np

img = cv2.imread("result.jpg",0)
cv2.imwrite("canny.jpg",cv2.Canny(img,200,300))
cv2.imshow("canny",cv2.imread("canny.jpg"))
cv2.waitKey()
cv2.destroyAllWindows()

原图:

opencv 三维坐标系 opencv显示三维图像_计算机视觉_03

运行结果:

opencv 三维坐标系 opencv显示三维图像_图像处理_04


opencv 三维坐标系 opencv显示三维图像_计算机视觉_05

2.8 轮廓检测

这段代码首先创建了一个200 x 200大小的黑色空白图像,接着在图像的中央放置一个白色方块,这里用到了np数组在切片上赋值的功能。接下来对图像进行二值化操作,然后调用了findContours()函数。该函数有三个参数:输人图像、层次类型和轮廓逼近方法。它有几个方面特别有趣:

这个函数会修改输人图像,因此建议使用原始图像的-份拷贝 (比如说,通过img.copy()来作为输人图像)。
由函数返回的层次树相当重要:cv2.RETR_TREE参数会得到图像中轮廓的整体层次结构,以此来建立轮廓之间的“关系”。
如果只想得到最外面的轮廓,可使用cv2.RETR_ EXTERNAL。这对消除包含在其他轮廓中的轮廓很有用(比如,在大多数情形下,不需要检测一个目标包含在另一个与之相同的目标里面)。

findContours()函数有三个返回值:修改后的图像、图像的轮廓以及它们的层次。
用轮廓来画出图像的彩色版本(即把轮廓画成绿色),并显示出来。所得的结果是一个边缘为绿色的白色方块。

import cv2
import numpy as np

img = np.zeros((200,200),dtype=np.uint8)
img[50:150,50:150] = 255

ret,thresh = cv2.threshold(img,127,255,0)
image,contours,hieraerchy  = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
color = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)
img = cv2.drawContours(color,contours,-1,(0,255,0),2)
cv2.imshow('contours',color)
cv2.waitKey()
cv2.destroyAllWindows()

运行结果:

opencv 三维坐标系 opencv显示三维图像_ci_06

2.9 边界框、最小矩形区域和最小闭圆的轮廓

import cv2
import numpy as np

img = cv2.pyrDown(cv2.imread('sq.jpg',cv2.IMREAD_UNCHANGED))

ret,thresh = cv2.threshold(cv2.cvtColor(img.copy(),cv2.COLOR_BGR2GRAY),127,255,cv2.THRESH_BINARY)
image,contours,hier = cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

for c in contours:
    #find bounding box coordinates
    x,y,w,h = cv2.boundingRect(c)
    cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
    
    #find minimum area
    rect = cv2.minAreaRect(c)
    #calculate coordinates of the minimum area rectangle
    box = cv2.boxPoints(rect)
    #normalize coordinates to integers
    box = np.int0(box)
    #draw contours
    cv2.drawContours(img,[box],0,(0,0,255),3)
    
    #calculate center and radius of minimum enclosing circle
    (x,y),radius = cv2.minEnclosingCircle(c)
    #cast to integers
    center = (int(x),int(y))
    radius = int(radius)
    #draw the circle
    img = cv2.circle(img,center,radius,(0,255,0),2)
    
cv2.drawContours(img,contours,-1,(255,0,0),1)
cv2.imshow("contours",img)
cv2.waitKey()
cv2.destroyAllWindows()

原图:

opencv 三维坐标系 opencv显示三维图像_计算机视觉_07


运行结果:

opencv 三维坐标系 opencv显示三维图像_opencv 三维坐标系_08

2.10 凸轮廓与Douglas-Peucker算法

cv2.approxPloyDP(cnt,epsion,True) 参数一:轮廓
参数二:ε值,表示源轮廓与近似多边形的最大差值(这个值越小,近似多边形与源轮廓周长之间的最大差值,这个差值越小,近似多边形与源轮廓就越相似)
参数三:布尔标记,表示这个多边形是否闭合

cv2.convexHull(cnt)获取处理过的轮廓信息

2.11 直线和圆检测

2.11.1 直线检测

2.11.2 圆检测

import cv2
import numpy as np

planets = cv2.imread('result.jpg')
gray_img = cv2.cvtColor(planets,cv2.COLOR_BGR2GRAY)
img = cv2.medianBlur(gray_img,5)
cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)

circles = cv2.HoughCircles(img,cv2.HOUGH_GRADIENT,1,120,param1=100,param2=30,minRadius=0,maxRadius=0)
circles = np.uint16(np.around(circles))

for i in circles[0,:]:
    #draw the outer circle
    cv2.circle(planets,(i[0],i[1]),i[2],(0,255,0),2)
    #draw the center of the circle
    cv2.circle(planets,(i[0],i[1]),2,(0,0,255),3)
    
cv2.imwrite("planets.jpg",planets)
cv2.imshow("HoughCircles",planets)
cv2.waitKey()
cv2.destroyAllWindows()

原图:

opencv 三维坐标系 opencv显示三维图像_ci_09


运行结果:

opencv 三维坐标系 opencv显示三维图像_opencv_10


opencv 三维坐标系 opencv显示三维图像_ci_11