1.1图形平移
设置图形平移矩阵:
M=np.float32([[x1,y1,val1],[x2,y2,val2]]) #x:坐标参数,val:平移像素位
图形实现平移:
image1=cv2.warpAffine(image,M,(image.shape[1],image.shape[0])) #image:平
移对象 M:平移矩阵 参数三:画布大小
1.2图形旋转
设置图形旋转矩阵:
M=cv2.getRotationMatrix2D((cX,cY),45,1.0) #图像旋转矩阵设置,第一个参数,旋转圆心,第二个参数:旋转角度,第三个参数:旋转后的缩放比例
图形实现旋转:
rotated=cv2.warpAffine(image,M,(w,h))#图像旋转,旋转图像,旋转矩阵,旋转后图像尺寸
1.3图像缩放
获取新图新与元图形尺寸比例:r = 150.0 / image.shape[1] #获取横向比例(坐标)
设置新图形的尺寸宽,长大小:dim = (150, int(image.shape[0]) * r) #设置图像横向和纵向的尺寸
将图形转化:resized = cv2.resize(image, dim, interpolation = cv2.INTER_AREA) #第一个参数:被处理对象,第二个参数:缩放比例,第三个参数:缩放后图形处理方式
图像处理方式:
cv2.INTER_NEAREST插值法:检查像素的邻域,并使用这些邻域光学地增加或减小图像的大小,而不引入失真(或
至少尽可能少的失真)。
cv2.INTER_LINEAR双线性插值:不仅仅是简单地找到“最近”的像素并假设它的价值(如最近邻插值) - 现在我
们正在拍摄邻近的像素并使用这个邻域实际上计算内插值应该是什么(而不是假设最近的像素值)
cv2.INTER_CUBIC双三次插值:因为它们不再使用简单的线性插值,而是使用样条),并且在平方像素邻域上使用
双三次插值(4 x 4像素邻居)
cv2.INTER_LANCZOS4双三次插值:因为它们不再使用简单的线性插值,而是使用样条),并且在平方像素邻域上使用双三次插值(8 x 8像素邻居)
1.4图像翻转
flipped = cv2.flip(image, 1) #参数1:翻转对象 参数2:翻转方式 0:表示横向翻转 1:表示竖直方向翻转 -1:
表示竖向翻转后,横向翻转
1.5图像裁切
face = image[35:468, 405:1136]#face:新裁切出来的对象 image:被裁切对象,参数一:竖直(高 y)方向裁切的
起点像素与终点像素。参数二:水平(宽 x)方向裁切的起点与终点
1.6亮度的增加与减少
M=np.ones(image.shape,dtype="uint8")*100 #定义一个NumPy数组,变化值为100
added=cv2.add(image,M) #增加亮度
M=np.ones(image.shape,dtype="uint8")*50#定义一个NumPy数组,变化值为50
subtracted=cv2.subtract(image,M) #减少亮度
1.7图像的像素按位操作
bitwiseAnd=cv2.bitwise_and(rectangle,circle)
加粗处可替换
and:当且仅当两个像素都大于零时, 按位AND是真的。
or:如果两个像素中的任一个大于零,则按位或为真。
xor:当且仅当两个像素中的一个大于零时, 按位XOR才为真,但不能同时为这两个。
not:按位不反转图像中的“开”和“关”像素。
1.8掩蔽
#画个白色矩形框
cv2.rectangle(mask, (419, 68), (1100, 485), 255, -1) #起点坐标与终点坐标,(x(宽度,水平方
向),y(高度,竖直方向))
cv2.imshow("Mask", mask)
#运用位运算操作关系,获取指定范围图像
masked = cv2.bitwise_and(image, image, mask = mask)
cv2.imshow("Mask Applied to Image", masked)
cv2.waitKey(0)
补充:
image=cv2.imread("路径") #从磁盘中获取图片
tr=image[0:cY,cX:w] #图像切片 第一个参数:裁切的高度,起点高度位置,结束点高度位置。第二个参数:
裁切的宽度,起点的宽度(x)位置,终点的宽度(x)位置
cv2.imshow("窗口名字",image) #图片加载到窗口
cv2.imwrite("路径",image) #将图片存入指定路径
图像绘制:
#设置画布大小
canvas=np.zeros((300,300,3),dtype="uint8")
#设置线条颜色为绿色
green=(0,255,0)
#设置直线起点坐标位置和终点坐标位置
cv2.line(canvas,(0,0),(300,300),green) #第一个参数被绘制的图像,可添加第6个参数:线条的厚度
#矩形绘制
cv2.rectangle(canvas,(10,10),(60,60),green) #第一个参数被绘制的图像,可添加第6个参数:线条的
厚度,如果为负数,表示填充
#圆形绘制
cv2.circle(canvas,(centerX,centerY),r,white)#第一个参数被绘制的图像,可添加第6个参数:线条的
厚度,如果为负数,表示填充
抓取图像某个像素点的RGB值:
(b,g,r)=image[0,0]
print"Pixel at (0, 0) - Red: {r}, Green: {g}, Blue: {b}".format(r=r,g=g,b=b)
1.9形态操作
侵蚀操作:eroded = cv2.erode(image, None, iterations = i + 1) #第二个参数:erode的结构元素,
第三个参数:侵蚀的程度
扩张操作:dilated= cv2.dilate(gray.copy(), None, iterations = i + 1)#第二个参数:dilate的结
构元素,第三个参数:扩张的程度
开盘、闭幕、形态梯度操作:
kernelSizes = [(3, 3), (5, 5), (7, 7)]
for kernelSize in kernelSizes:
#参数1:结构化元素的类参数2:构造元素的大小
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, kernelSize)
#参数1:运算的图像参数2:实际类型 参数3:使用的内核/结构化元素。
opening = cv2.morphologyEx(gray1, 操作类型, kernel)
操作类型:开盘:cv2.MORPH_OPEN
闭幕:cv2.MORPH_CLOSE
形态梯度:cv2.MORPH_GRADIENT
顶帽操作:cv2.MORPH_BLACKHAT
黑帽操作:cv2.MORPH_TOPHAT
1.10 平滑和模糊处理
平均模糊处理:blurred=cv2.blur(image,(kX,kY)) #参数1:被处理对象 参数2:内核矩阵尺寸
高斯模糊处理:blurred=cv2.GaussianBlur(image,(kX,kY),0)#参数1:被处理对象 参数2:
内核矩阵尺寸 参数3:标准偏差
中位数模糊处理:blurred=cv2.medianBlur(image,k)#参数1:被处理对象 参数2:中位数值
双边模糊处理:blurred=cv2.bilateralFilter(image,diameter,sigmaColor,sigmaSpace)
#参数1:被处理对象,参数2:直径,参数3:\ sigma_ {颜色}参数4:\ sigma_ {空间}
1.11 照明和色彩空间
RGB:获取各个通道空间颜色并显示
for(name,chan)inzip(("B","G","R"),cv2.split(image)):
cv2.imshow(name,chan)
HSV:
for(name,chan)inzip(("H","S","V"),cv2.split(hsv)):
cv2.imshow(name,chan)
L* a* b*:
for(name,chan)inzip(("L*","a*","b*"),cv2.split(lab)):
cv2.imshow(name,chan)
灰度:
gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
1.12简单阀值
阀值函数:(T,thresh)=cv2.threshold(blurred,200,255,cv2.THRESH_BINARY) #参数1:阀值
的灰度图像 #参数2:设置的阀值T 参数3:阀值期间应用的输出值,将像素强度大于T的设置为零,将小于T的设
置为参数3的值 参数4:阀值方法
大津方法:(T,threshInv)=cv2.threshold(blurred,0,255,cv2.THRESH_BINARY_INV|cv2.THRESH_OTSU)
#参数2:由程序分析获取
1.13 Sobel内核
gX=cv2.Sobel(gray,ddepth=cv2.CV_64F,dx=1,dy=0) #计算跨x方向的梯度
gY=cv2.Sobel(gray,ddepth=cv2.CV_64F,dx=0,dy=1) #计算y方向上的梯度
gX=cv2.convertScaleAbs(gX) #让图像在屏幕上可视化,将数据转换成8位无符号整数
gY=cv2.convertScaleAbs(gY)#让图像在屏幕上可视化,将数据转换成8位无符号整数
sobelCombined=cv2.addWeighted(gX,0.5,gY,0.5,0)#cv2将gX和gy组合成单个图像
addWeighted函数,平均加权每个梯度表示
OpenCV中的渐变方向和幅度
ap.add_argument("-i","--image",required=True,help="Path to the image")
#路径到我们的形象驻留在磁盘上
ap.add_argument("-l","--lower-angle",type=float,default=175.0,help="L
ower orientation angle")
#- 低级- 角度 ,或最小 梯度方向的角度,我们感兴趣的检测- 上- 的角度
ap.add_argument("-u","--upper-angle",type=float,default=180.0,help="Up
per orientation angle")
gX=cv2.Sobel(gray,cv2.CV_64F,1,0)#Sobel滤波器计算x的梯度
gY=cv2.Sobel(gray,cv2.CV_64F,0,1)#Sobel滤波器计算y的梯度
mag=np.sqrt((gX**2)+(gY**2)) #梯度幅值计算,两者的平方梯度的平方根x和y相
加方向
orientation=np.arctan2(gY,gX)*(180/np.pi)%180 #梯度方向计算,将两个
梯度的反正切x和x方向
idxs=np.where(orientation>=args["lower_angle"],orientation,-1)#手柄选
择是图像坐标更大比的角度最小更低。参数1:寻找大于最小提供角度的索引。参数2:方向阵列 参数3:
特定值设置为-1
idxs=np.where(orientation<=args["upper_angle"],idxs,-1)
mask=np.zeros(gray.shape,dtype="uint8")
mask[idxs>-1]=255
1.14 查找和绘制轮廓
(cnts,_)=cv2.findContours(gray.copy(),cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE) #寻找
轮廓区域
#参数1:操作对象输入图像具有破坏性(意味着它会操作它),所以对对象复制一下
#参数2:该标志将确保返回所有轮廓
clone=image.copy()
cv2.drawContours(clone,cnts,-1,(0,255,0),2)
1.15 简单轮廓属性
质心:图像中物体的中心(x,y)坐标,(x,y)坐标实际上是基于基于沿轮廓的(x,y)坐标/像素强度的加权平
均值
(cnts,_)=cv2.findContours(gray.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)#寻找轮廓区域
clone=image.copy()
forcincnts:
M=cv2.moments(c)
cX=int(M["m10"]/M["m00"])
cY=int(M["m01"]/M["m00"])
cv2.circle(clone,(cX,cY),10,(0,255,0),-1)
面积和周长:
for(i,c)inenumerate(cnts):
area=cv2.contourArea(c)
perimeter=cv2.arcLength(c,True)
print"Contour #%d -- area: %.2f, perimeter: %.2f"%(i+1,area,perimeter)
cv2.drawContours(clone,[c],-1,(0,255,0),2)
M=cv2.moments(c)
cX=int(M["m10"]/M["m00"])
cY=int(M["m01"]/M["m00"])
cv2.putText(clone,"#%d"%(i+1),(cX-20,cY),cv2.FONT_HERSHEY_SIMPLEX,
1.25,(255,255,255),4)
旋转边框:
forcincnts:
# fit a rotated bounding box to the contour and draw a rotated bounding box
box=cv2.minAreaRect(c)
box=np.int0(cv2.cv.BoxPoints(box))
cv2.drawContours(clone,[box],-1,(0,255,0),2)
# show the output image
cv2.imshow("Rotated Bounding Boxes",clone)
cv2.waitKey(0)
clone=image.copy()
最小封闭圆:
forcincnts:
((x,y),radius)=cv2.minEnclosingCircle(c)
cv2.circle(clone,(int(x),int(y)),int(radius),(0,255,0),2)
装配椭圆:
forcincnts:
iflen(c)>=5:
ellipse=cv2.fitEllipse(c)
cv2.ellipse(clone,ellipse,(0,255,0),2)
1.16高级轮廓属性
长宽比:使用宽高比来区分正方形和矩形,并检测图像中的手写数字,并从其余轮廓中剪除它们
程度:形状或轮廓的是轮廓区域边界框面积的比例
凸海鸥:
密实度:轮廓面积/凸包面积
hull=cv2.convexHull(c) #形状的实际凸包
hullArea=cv2.contourArea(hull)#凸包面积
for(i,c)inenumerate(cnts):
area=cv2.contourArea(c) #遍历所有图片轮廓
(x,y,w,h)=cv2.boundingRect(c) #获取轮廓边界
aspectRatio=w/float(h) #计算宽高比
extent=area/float(w*h) # 获取范围
#计算凸包和坚固度
hull=cv2.convexHull(c)
hullArea=cv2.contourArea(hull)
solidity=area/float(hullArea)
cv2.drawContours(hullImage,[hull],-1,255,-1)
cv2.drawContours(image,[c],-1,(240,0,159),3)
shape=""
1.17轮廓近似
forcincnts:
peri=cv2.arcLength(c,True)
approx=cv2.approxPolyDP(c,0.01*peri,True) #第而个参数使用特殊值
iflen(approx)==4:
cv2.drawContours(image,[c],-1,(0,255,255),2)
(x,y,w,h)=cv2.boundingRect(approx)
cv2.putText(image,"Rectangle",(x,y-10),cv2.FONT_HERSHEY_SIMPLEX,
0.5,(0,255,255),2)
疑惑总结:
1、形态操作中,如何定义构造元素?
侵蚀操作:eroded = cv2.erode(image, None, iterations = i + 1) #第二个参数:erode的结构元素,
第三个参数:侵蚀的程度
2、轮廓检测检测中,为什么只能检测测试图片
3、轮廓识别过程中,:image1=cv2.warpAffine(image,M,(image.shape[1],image.shape[0])) #image:平
移对象 M:平移矩阵 参数三:画布大小