【原创】python opencv基础

目录

图像的读取、显示与保存

读取图像高度、宽度、通道数等属性信息

访问图片像素点或像素块(ROI)

访问各个通道的数据

图像的缩放

图像二值化

按位操作

opencv中的计时函数  getTickCount()和getTickFrequency()

cv2.inRange()获取指定区域的像素

图像平移

图像旋转

图像平滑


查找OpenCV中函数,数据类型等关键

查看函数的帮助

import cv2

print [x for x in dir(cv2) if x.startswith('CV_')]
'''
['CV_16S', 'CV_16SC1', 'CV_16SC2', 'CV_16SC3', 'CV_16SC4', 'CV_16U', 'CV_16UC1', 'CV_16UC2', 'CV_16UC3', 'CV_16UC4', 'CV_32F', 'CV_32FC1', 'CV_32FC2', 'CV_32FC3', 'CV_32FC4', 'CV_32S', 'CV_32SC1', 'CV_32SC2', 'CV_32SC3', 'CV_32SC4', 'CV_64F', 'CV_64FC1', 'CV_64FC2', 'CV_64FC3', 'CV_64FC4', 'CV_8S', 'CV_8SC1', 'CV_8SC2', 'CV_8SC3', 'CV_8SC4', 'CV_8U', 'CV_8UC1', 'CV_8UC2', 'CV_8UC3', 'CV_8UC4']
'''

print [x for x in dir(cv2) if x.find('resize')>0]
'''
['resize', 'resizeWindow']
''' 

help(cv2.erode)
'''
erode(...)
    erode(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]]) -> dst
'''

图像的读取、显示与保存

import cv2
import numpy as np

im = cv2.imread('lena.jpg')    #读取RGB彩色图片
im_gray = cv2.imread('lena.jpg', 0)    #读取灰度图
im_gray_cvt = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)    #RGB图转灰度图


cv2.imshow('color image', im)    #显示图片
cv2.waiKey(0)        #图片显示时间设定, 0代表一直显示,直到有键盘输入 

cv2.imwrite("lena2.jpg", im)    #保存图片   
cv2.imwrite('lina_jpeg_quality_90.jpg', im, [int(cv2.IMWRITE_JPEG_QUALITY), 90])
cv2.imwrite('line_png_compress_2.png', im, [int(cv2.IMWRITE_PNG_COMPRESSION), 2])

cv2.imwrite函数的第三个参数指定保存图像的质量或者压缩率。对于jpeg,其表示图像的质量,0-100,数值越大图像质量越好,默认值是95。对于png,设置的值压缩率,0-9,数值越大压缩率越高,图像越小。

读取图像高度、宽度、通道数等属性信息

import cv2
import numpy as np

im = cv2.imread('lena.jpg')

rows, cols, channels = im.shape
heights, width, channels = im.shape

print im.shape
print 'row number:',rows, 'col number:',cols, 'channels:',channels

print 'image size:', im.size
print 'image data type', im.dtype

访问图片像素点或像素块(ROI)

import cv2
import numpy as np


im = cv2.imread('lena.jpg')

print im[50, 100]    
print im[50, 100, 0]


im[50, 100] = [0,0,0]
im[50, 100, 0] = 255


cv2.imshow('im', im)
cv2.waitKey() 

直接访问像素是速度慢,意义不大,在图像处理时常常会访问一块区域,这块区域称为ROI(region of interest)

#coding: utf-8
'''
    交换两个指定区域
'''
import numpy as np
import cv2


im = cv2.imread('images/roi.jpg')
ball = im[280:340, 330:390]
im[273:333, 100:160] = ball

cv2.imshow('roi', im)
cv2.waitKey()

访问各个通道的数据

import cv2 
import numpy as np


im = cv2.imread('images/lena.jpg')
b = im[:, :, 0]
g = im[:, :, 1]
r = im[:, :, 2]

im1 = cv2.merge((b, g, r))
im1[:, :, 2] = 0     #直接设置红色通道值

cv2.imshow('im1', im1)
cv2.imshow('im', im)

cv2.waitKey()

图像的缩放

cv2.resize(src, dsize, dst, fx, fy, interpolation) → dst

缩小时推荐使用interpolation= cv2.INTER_AREA,放大时推荐使用interpolation=cv2.INTER_LINEAR(默认算法)

import cv2
import numpy as np


im = cv2.imread('images/lena.jpg')
h, w = im.shape[:2]
#指定缩放后的大小
#放大时推荐使用默认的差值算法cv2.INTER_AREA
im_big = cv2.resize(im, (2*h, 2*w))

#指定缩放比例,注意None, fx,fy均不能胜率
#缩小时推荐指定差值算法为cv2.INTER_AREA
im_small = cv2.resize(im, None, fx=0.5, fx=0.5,  interpolation= cv2.INTER_AREA)


cv2.imshow('origin', im)
cv2.imshow('small', im_small)
cv2.imshow('big', im_big)
cv2.waitKey()

图像二值化

import cv2
import numpy as np 

im = cv2.imread('images/gradient.jpg', 0)

ret, thresh1 = cv2.threshold(im, 127, 255, cv2.THRESH_BINARY)
ret, thresh2 = cv2.threshold(im, 127, 255, cv2.THRESH_BINARY_INV)
ret, thresh3 = cv2.threshold(im, 127, 255, cv2.THRESH_TRUNC)
ret, thresh4 = cv2.threshold(im, 127, 255, cv2.THRESH_TOZERO)
ret, thresh5 = cv2.threshold(im, 127, 255, cv2.THRESH_TOZERO_INV)

cv2.imshow('origin', im)
cv2.imshow('binary', thresh1)
cv2.imshow('binary inv', thresh2)
cv2.imshow('trunc', thresh3)
cv2.imshow('to zero', thresh4)
cv2.imshow('to zero inv', thresh5)

cv2.watiKey()

图像边缘扩充

import cv2
import numpy as np

white = [255,255, 255]

im = cv2.imread('images/opencv_log.jpg')
#top  bottom  left ,right
im1 = cv2.copyMakeBorder(im, 10, 10, 10, 10, cv2.BORDER_CONSTANT, value = white)

cv2.imshow('white border', im1)
cv2.waitKey()

copyMakeBorder第2-5个参数分别是:top,bottom,left,right。

第5个参数表示要填充边界的类型:

  • cv2.BORDER_CONSTANT 添加有颜色的常数值边界,还需要下一个参数(value)。
  • cv2.BORDER_REFLECT 边界元素的镜像。比如: fedcba|abcdefgh|hgfedcb
  • cv2.BORDER_REFLECT_101 or cv2.BORDER_DEFAULT跟上面一样,但稍作改动。例如: gfedcb|abcdefgh|gfedcba
  •  cv2.BORDER_REPLICATE 重复最后一个元素。例如: aaaaaa|abcdefgh|hhhhhhh
  • cv2.BORDER_WRAP 不知道怎么说了, 就像这样: cdefgh|abcdefgh|abcdefg

value 边界颜色,如果边界的类型是cv2.BORDER_CONSTANT

按位操作

按位操作包括: bitwise_and(与),bitewise_or(或), bitewise_not(非) , bitewise_xor(异或)

cv2.bitewise_and(im1, im2, dst, mask=mask)

计算在两个阵列或阵列和标量,每个元素逐位与操作。如果设置mask,在mask!=0,进行与操作,其余位置设置为0

import cv2
import numpy as np

# 加载图像
img1 = cv2.imread('images/roi.jpg')
img2 = cv2.imread('images/opencv_logo.jpg')

# I want to put logo on top-left corner, So I create a ROI
rows,cols,channels = img2.shape
roi = img1[0:rows, 0:cols ]

# Now create a mask of logo and create its inverse mask also
img2gray = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)

ret, mask = cv2.threshold(img2gray, 175, 255, cv2.THRESH_BINARY)
mask_inv = cv2.bitwise_not(mask)
cv2.imshow('mask', mask)
cv2.imshow('mask inv', mask_inv)

# 取logo图中非logo部分
img1_bg = cv2.bitwise_and(roi,roi,mask = mask)
cv2.imshow('img1_bg',img1_bg)

# 取logo图中logo部分
img2_fg = cv2.bitwise_and(img2,img2,mask = mask_inv)
cv2.imshow('img2_fg',img2_fg)

# Put logo in ROI and modify the main image
dst = cv2.add(img1_bg,img2_fg)
img1[0:rows, 0:cols ] = dst
cv2.imshow('res',img1)
cv2.waitKey(0)
cv2.destroyAllWindows()

opencv中的计时函数  getTickCount()和getTickFrequency()

import cv2 
import numpy as np

im = cv2.imread('images/roi.jpg')
m2 = cv2.medianBlur(im, 3)

for x in range(3,12,2):
	t1 = cv2.getTickCount()
	im2 = cv2.medianBlur(im, x)
	t2 = cv2.getTickCount()
	print  'median kernel:', x, 'using time:',(t2-t1)/cv2.getTickFrequency(), 's'

第一次计时是不准确的,所有需要先计算一次

cv2.inRange()获取指定区域的像素

mport cv2
import numpy as np

im = cv2.imread('images/lena.jpg')
hsv = cv2.cvtColor(im, cv2.COLOR_BGR2HSV)

lower_red = np.array([20,20,20])
upper_red = np.array([200,200,200])

mask_red = cv2.inRange(hsv, lower_red, upper_red)
res_red = cv2.bitwise_and(im, im, mask=mask_red)
cv2.imshow("red", res_red)


lower_blue = np.array([100,47,47])
upper_blue = np.array([124,255,255])
mask_blue = cv2.inRange(hsv, lower_blue, upper_blue)
res_blue = cv2.bitwise_and(im, im, mask=mask_blue)
cv2.imshow("blue", res_blue)


cv2.waitKey()

inRange函数,要求图像像素的每个通道值,都要大于等于lower对应通道值,都要小于等于upper对应通道的值

图像平移

图像平移使用仿射变换函数warpAffine实现,首先创建一个变换矩阵M,通过M计算原图中像素点(x,y),在生成图中新位置(x1,y1)

import cv2
import  numpy as  np


im  = cv2.imread('messi.jpg')

#平移矩阵,原坐标(0,0)的像素点在新图中的像素点(100, 50)
#由于使用了坐标位置,100为列位置,50为行位置
#注意矩阵必须是浮点型的
M = np.array([[1,0,100], [1,0,50]], dtype=np.float32)

#第三个参数设定生成图的大小,这个依然是使用坐标系,即显示列坐标,后是行坐标
im_warp = cv2.warpAffine(im, M, im.shape[:2][-1])
cv2.imshow('origin', im)
cv2.imshow('warp', im_warp)
cv2.waitKey()

图像旋转

图像旋转也是通过仿射变换函数warpAffine实现的,不过首先通过getRotationMatrix2D获得旋转矩阵M

import cv2
import numpy as np

im = cv2.imread('images/messi.jpg')

#创建旋转矩阵
#参数分别是:旋转中心点, 旋转后角度,旋转后的缩放比例
M = cv2.getRotationMatrix2D((im.shape[1]/2, im.shape[0]/2), 90, 0.6)

im_res = cv2.warpAffine(im, M, (im.shape[1], im.shape[0]))

cv2.imshow('origin', im)
cv2.imshow('rotation', im_res)
cv2.waitKey()

图像平滑

平滑的效果就是使得低频信号通过,高频信号被过滤

import sys
import numpy as np
import cv2
from matplotlib import pyplot as plt

im_path = sys.argv[1]
im = cv2.imread(im_path)
im = cv2.cvtColor(im, cv2.COLOR_BGR2RGB)
if im is None:
	print im_path, ' not exist'
	sys.exit()

blur = cv2.blur(im, (5,5))
gaussian_blur = cv2.GaussianBlur(im, (5,5), 0)
median_blur = cv2.medianBlur(im, 5)
bilateral_filter = cv2.bilateralFilter(im, 9, 75, 75)

plt.subplot(2,2,1), plt.imshow(im), plt.title('origin'), plt.xticks([]),plt.yticks([])
plt.subplot(2,2,2), plt.imshow(blur), plt.title('blur'), plt.xticks([]),plt.yticks([])
plt.subplot(2,2,3), plt.imshow(gaussian_blur), plt.title('gaussian blur'), plt.xticks([]),plt.yticks([])
plt.subplot(2,2,4), plt.imshow(bilateral_filter), plt.title('bilateral filter'), plt.xticks([]),plt.yticks([])

plt.show()

cv2.blur()为均值滤波,滤波器覆盖的像素都权重都是一样的。

cv2.GaussianBlur()是高斯滤波,滤波器覆盖的像素点是有权重,权重符合均值为0的正态分布

cv2.bilateralFilter()是双边滤波,考虑根据像素点的相对位置增加空间高斯权重外,还会根据像素点和中心像灰度差增加灰度相似权重。由于存在灰度相似权重,边界的像素点就不会被模糊掉,物体内部的噪声点就会被模糊掉,这个很奇妙。

图像上的算术运算

OpenCV算术运算可以使用cv2.add(), cv2.subtract()等API,也可以直接使用numpy, res = im1+ im2,使用numpy操作时,两张图片数据类型必须一致,或者第二个是一个标量。

注意:OpenCV的加法运算是饱和操作,numpy的加法运算是溢出操作。例如

x1 = np.uint8([250])
x2 = np.uint8([10])

print cv2.add(x1, x2)    #输出255,饱和操作,一旦到达或超过上线时,输出值都是上线
print x+y            #输出4, 溢出操作,超过255后会变成0,1,2,3,4

这种差别在使用两张图片的加法时会更明显,如果使用numpy会有很多溢出操作,所以最好使用OPenCV的函数。

图像的混合

其实也是一种加法操作,但是两幅图像的权重不同,给人一种混合和透明的感觉。图像混合的公式是:

import cv2 
import numpy as np

im1 = cv2.imread('images/ml.jpg')
im2 = cv2.imread('images/blending.jpg')

dst = cv2.addWeighted(im1, 0.7, im2, 0.3, 0)

cv2.imshow('dst', dst)
cv2.waitKey(0)

参数包括   img1, img1的权重, img2, img2的权重,偏移量,输出的图像depth

图像的梯度

import cv2
import numpy as np
import sys
from matplotlib import pyplot as plt 
im = cv2.imread(sys.argv[1], 0)

if im is None:
	print sys.argv[1], 'not exist'
	sys.exit()


cv2.imshow('oringin', im)
laplacian  = cv2.Laplacian(im, cv2.CV_64F)
sobelX = cv2.Sobel(im, cv2.CV_64F, 1, 0, ksize=5)
sobelY = cv2.Sobel(im, cv2.CV_64F, 0, 1, ksize=5)


plt.subplot(2,2,1), plt.imshow(im, 'gray')
plt.xticks([]), plt.yticks([]), plt.title('Original')
plt.subplot(2,2,2), plt.imshow(laplacian, 'gray')
plt.xticks([]), plt.yticks([]), plt.title('laplacian')
plt.subplot(2,2,3), plt.imshow(sobelX, 'gray')
plt.xticks([]), plt.yticks([]), plt.title('Sobelx')
plt.subplot(2,2,4), plt.imshow(sobelY, 'gray')
plt.xticks([]), plt.yticks([]), plt.title('Sobely')

cv2.imshow('laplacian', laplacian)
cv2.imshow('sobelX', sobelX)
cv2.imshow('sobleY', sobelY)

cv2.waitKey()
plt.show()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值