Python-OpenCV图像处理笔记

数据读取-图像

OpenCV中读取的图像格式为BGR

·cv2.IMREAD_COLOR: 彩色图像

·cv2.IMREAS_COLOR: 灰色图像

img=cv2.imread('xxx.jpg')
#图像的显示,也可以创建多个窗口
cv2.imshow('image',img)
#等待时间(多少毫秒),0表示任意键终止
cv2.waitKey(0)
cv2.destroyAllWindows()

·多张图片读取,可以先定义一个函数调用即可:

def cv_show(name,img):
    cv2.imshow(name,img)
    cv2.waitKey(0)
    cv2.destroyALLWindows()

·一些操作

#查看图像数值
#例如(400,400,3)分别为(h,w,c)高宽和三个图层
img.shape
#保存
cv2.imwrite('xxx.jpg',img)
#二值化操作的类型
type(img)
#像素点个数
img.size
#数据类型
img.dtype

数据读取-视频

vc = cv2.VideoCapture('xxx.mp4')
#检测是否能打开视频
if vc. isOpened():
      open, frame = vc.read()
else:
      open = False
#循环播放每一帧图像
while open:
      ret, frame = vc.read()
       if frame is None:
           break
       if ret == Ture:
           gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
           cv2.imshow('result', gray)
           if cv2.waitKey(10) & oxFF == 27: #27为键盘上的退出键
                 break
vc.release()
cv2.destroyAllWIndows()

截取部分图像数据

img=cv2.imread('xxx.jpg')
result=img[0:200,0:200]
cv_show('result',result)

颜色通道的提取

#分开BGR
b,g,r=cv2.split(img)
#只保留R
cur_img = img.copy()
cur_img[:,;,0] = 0    #BGR分别为0,1,2
cur_img[;,;,1] = 0    #只保留BG同理
cv_show('R',cur_img)

边界填充

top_size,bottom_size,left_size,right_size = (50,50,50,50)

#复制法,复制最边缘像素
replicate = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size, borderType=cv2.BORDER_REPLICATE)

#反射法,对感兴趣的像素在两边复制,如:fedcba|abcdefgh|hgfedcb
reflect = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size, borderType=cv2.BORDER_REFLECT)

#反射法,以最边缘像素为轴对称,如:gfedcb|abcdefgh|gfedcba
reflect101 = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size, borderType=cv2.BORDER_REFLECT_101)

#外包法,如:cdefgh|abcdefgh|abcdefg
wrap = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size, borderType=cv2.BORDER_WRAP)

#常量法,用常数填充
constant = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size, borderType=cv2.BORDER_CONSTANT, value=0)

数值计算

#图像的每个像素点都加10
img_i = img_i +10

两个图像相加,像素点之和结果%256

图像融合

img_demo1 + img_demo2     #两个图像的shape值要一致才行

#修改shape值
img_demo1 = cv2.resize(img_demo1, (xxx,xxx))
img_demo1 = cv2.resize(img_demo1, (xxx,xxx), fx=3, fy=2)  #3,2分别为x,y的倍数

#加权相加
res = cv2.addWeighted(img_demo1, 0.4, img_demo2, 0.5, 0) # res=0.4*demo1+0.5*demo2+0

图像阈值

#超过阈值部分取maxval(最大值),否则取0
ret. thresh1 = cv2.threshold(img_gray, 127, 255, cv2.THRES_BINARY)
#上面的反转
ret. thresh2 = cv2.threshold(img_gray, 127, 255, cv2.THRES_BINARY_INV)  #INV为inverse
#大于阈值部分为阈值,其他不变
ret. thresh3 = cv2.threshold(img_gray, 127, 255, cv2.THRES_TRUNC)
#大于阈值的不变,其他为0
ret. thresh4 = cv2.threshold(img_gray, 127, 255, cv2.THRES_TOZERO)
#上面的反转
ret. thresh5 = cv2.threshold(img_gray, 127, 255, cv2.THRES_TOZERO_INV)
#127为阈值,255为最大值

图像平滑

#均值滤波,简单的平均卷积操作
blur = cv2.blur(img,(3,3)) #用3*3的单位矩阵卷积(一般都是奇数矩阵)
#方框滤波,类似均值滤波,可以选择归一化
box = cv2.boxFilter(img,-1,(3,3), normalize=True) #normalize=False容易越界
#高斯滤波,高斯模糊的卷积核数值满足高斯分布,相当于更重视
aussian = cv2.GaussianBlur(img. (5,5), 1)
#中值滤波,用中间值代替
median = cv2.medianBlur(img, 5)

#显示所有
res = np.hstack((blur,aussian,median)) #水平显示三张图像
res = np.vstack((blur,aussian,median)) #垂直显示三张图像

腐蚀操作

kernel = np.ones((5,5),np,uint8)
erosion = cv2.erode(img,kernel,iterations = 1)

膨胀操作

kernel = np.ones((5,5),np,uint8)
dilatability = cv2.dilate(img,kernel,iterations = 1)

开运算与闭运算

#开运算:先腐蚀后膨胀
kernel = np.ones((5,5),np,uint8)
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)

#闭运算:先膨胀后腐蚀
kernel = np.ones((5,5),np,uint8)
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)

梯度运算

#梯度=膨胀-腐蚀
gradient = cv2.morphologyEx(pie. cv2.MORPH_GARDIENT. kernel)

礼帽与黑帽

#礼帽=原始输入-开运算结果
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)

#黑帽=闭运算-原始输入
blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)

图像梯度-Sobel算子

dst = cv2.Sobel(src, ddepth, dx, dy, ksize)

#ddepth:图像深度
#dx和dy分别表示水平和竖直方向
#ksize是Sobel算子大小

sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3)
sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)
sobely = cv2.convertScaleAbs(sobely)
sobelxy = cv2.addWeighted(sobelx, 0.5, sobely, 0.5, 0)

白到黑为正数,黑到白为负数,所有负数都被截断成0,所以取其绝对值

x = cv2.convertScaleABs(x)

图像梯度-Scharr算子

scharrx = cv2.Scharr(img, cv2.CV_64F, 1, 0)
scharry = cv2.Scharr(img, cv2.CV_64F, 0, 1)
scharrx = cv2.convertScaleAbs(scharrx)
scharry = cv2.convertScaleAbs(scharry)
scharrxy = cv2.addWeighted(scharrx, 0.5, scharry, 0.5, 0)

图像梯度-laplacian算子

laplacian = cv2.Laplacian(img, cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian)

Canny边缘检测

1)使用高斯滤波器,用来平滑图像,滤除噪声

2)计算图像中每个像素点的梯度强度和方向

3)用非极大值抑制,消除边缘检测带来的杂散响应

4)运用双阈值来确定真实的和潜在的边缘

5)通过抑制孤立的弱边缘最终完成边缘检测

v=cv2.Canny(img, 50, 100)

图像金字塔

1)高斯金字塔

  • 向下采样(缩小)
  • 向上采用(放大)
#上采样
up=cv2.pyrUp(img)

#下采样
down=cv2.pyrDown(img)

2)拉普拉斯金字塔

  • 向下采样(缩小)
  • 向上采用(放大)

L = G - PyrUp(Pyrdown(G))            //G为图像img

图像轮廓

cv2.findContours(img, mode, method)

mode——轮廓检测模式

  • RETR_EXTERNAL:只检索最外面的轮廓
  • RETR_LIST:检索所有的轮廓,并将其保存到一条链表中
  • RETR_CCOMP:检索所有的轮廓,并将他们组织成两层:顶层是各部分的外部边界,第二层是空间的边界
  • RETR_TREE:检索所有的轮廓,并重构嵌套轮廓的整个层次

method——轮廓逼近方法

  • CHAIN_APPROX_NONE:以Freman链码的方式输出轮廓,所有其他方法输出多边形(顶点序列)
  • CHAIN_APPROX_SIMPLE:压缩水平的、垂直的和斜的部分,也就是,函数只保留他们的终点部分

为了更高的准确率,使用二值图像

img = cv2.imread('car.png')
gray = cv2tColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
cv_show(thresh,'thresh')

绘制轮廓

#传入绘制图像,轮廓,轮廓索引,颜色模式,线条厚度
#注意需要copy,否则原图会变
draw_img = img.copy()
res = cv2.drawContours(draw_img, contours, -1, (0, 0, 255), 2)
cv_show(res,'res')

轮廓特征

cnt = contours[0]

#面积
cv2.contoursArea(cnt)
#周长,True表示闭合的
cv2.arcLength(cnt,True)

轮廓近似

epsilon = 0.1*cv2.arcLength(cnt,True)
approx = cv2.apporxPolyDP(cnt,epsilon,True)

边界矩形

cnt = contours[3]
x,y,w,h = cv2.boundingRect(cnt)
img = cv2.rectangle(img, (x,y), (x+w,y+h), (0, 255, 0), 2)

外接圆

(x,y),radius = cv2.minEnclosingCircle(cnt)
center = (int(x), int(y))
radius = int(radius)

你可能感兴趣的:(opencv,python)