赞
踩
img = cv2.imread('5.jpg')
cv2.namedWindow('f',cv2.WINDOW_NORMAL)
cv2.imshow('f',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
BLUE=[255,0,0] img1=cv2.imread('logo.jpg') replicate = cv2.copyMakeBorder(img1,30,30,30,30,cv2.BORDER_REPLICATE) reflect = cv2.copyMakeBorder(img1,30,30,30,30,cv2.BORDER_REFLECT) reflect101 = cv2.copyMakeBorder(img1,30,30,30,30,cv2.BORDER_REFLECT_101) wrap = cv2.copyMakeBorder(img1,30,30,30,30,cv2.BORDER_WRAP) constant= cv2.copyMakeBorder(img1,30,30,30,30,cv2.BORDER_CONSTANT,value=BLUE) plt.subplot(231),plt.imshow(img1,'gray'),plt.title('ORIGINAL') plt.subplot(232),plt.imshow(replicate,'gray'),plt.title('REPLICATE') plt.subplot(233),plt.imshow(reflect,'gray'),plt.title('REFLECT') plt.subplot(234),plt.imshow(reflect101,'gray'),plt.title('REFLECT_101') plt.subplot(235),plt.imshow(wrap,'gray'),plt.title('WRAP') plt.subplot(236),plt.imshow(constant,'gray'),plt.title('CONSTANT') plt.show()
img1 = cv2.imread('5.jpg') img2 = cv2.imread('logo.jpg') rows,cols,channels = img2.shape roi = img1[0:rows, 0:cols ] img2gray = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY) ret, mask = cv2.threshold(img2gray, 175, 255, cv2.THRESH_BINARY) # 抠出前景 mask_inv = cv2.bitwise_not(mask) img1_bg = cv2.bitwise_and(roi,roi,mask = mask) # 注意是roi 区域 img2_fg = cv2.bitwise_and(img2,img2,mask = mask_inv) dst = cv2.add(img1_bg,img2_fg) img1[0:rows, 0:cols ] = dst cv2.imshow('res',img1) cv2.waitKey(0) cv2.destroyAllWindows()
cv2.getTickCount() # 返回时钟数 cv2.getTickFrequency() # 返回时钟频率
import cv2
import numpy as np
img1 = cv2.imread('5.jpg')
e1 = cv2.getTickCount() # or time.time() 但cv本身的函数肯定要好一些。。。
for i in range(5,49,2):
img1 = cv2.medianBlur(img1,i)
e2 = cv2.getTickCount()
t = (e2 - e1)/cv2.getTickFrequency()
print(t)
cv本身的函数经过优化是非常快的,在对视图复制时还是numpy 要快。
%timeit cv2.countNonZero(img1)
29.4 µs ± 867 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit np.count_nonzero(img1)
1.17 ms ± 92 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
green = np.uint8([[[0,255,0]]]) # 形式要正确,对应cvArray,cvMat,IplImage blue = np.uint8([[[0,0,255]]]) red = np.uint8([[[255,0,0]]]) hsv_green=cv2.cvtColor(green,cv2.COLOR_BGR2HSV) >>> array([[[ 60, 255, 255]]], dtype=uint8) # 阈值可以设为 [H-100,100,100] 和 [H+100,255,255] cap = cv2.VideoCapture(0) while (cap.isOpened()): ret,frame = cap.read() if ret: hsv = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV) lower_blue=np.array([100,50,50]) upper_blue=np.array([124,255,255]) lower_red=np.array([156,50,50]) upper_red=np.array([180,255,255]) lower_green=np.array([35,50,50]) upper_green=np.array([77,255,255]) mask1 = cv2.inRange(hsv,lower_blue,upper_blue) mask2 = cv2.inRange(hsv,lower_green,upper_green) mask3 = cv2.inRange(hsv,lower_red,upper_red) mask = cv2.bitwise_or(cv2.bitwise_or(mask1,mask2),mask3) dst = cv2.bitwise_and(frame,frame,mask=mask) cv2.imshow('frame',frame) cv2.imshow('mask',mask) cv2.imshow('dst',dst) if cv2.waitKey(1) == 27: break cv2.destroyAllWindows()
res = cv2.resize(img,None,fx=0.5,fy=0.5,interpolation = cv2.INTER_CUBIC)
x=cv2.flip(img,0) # 反转
M = np.float32([[1, 0, x], [0, 1, y]]) # x,y 对应 移动的距离
move=cv2.warpAffine(img,M,(width,height)) # 平移
M=cv2.getRotationMatrix2D((width/2,height/2),45,0.6) # 旋转
rotate=cv2.warpAffine(img,M,(width,height))
M=cv2.getAffineTransform(p1,p2) # 三个点 左上 右上 左下
dst=cv2.warpAffine(img,M,(cols,rows)) # 仿射
M=cv2.getPerspectiveTransform(pts1,pts2) # 四个点,
dst=cv2.warpPerspective(img,M,(300,300)) # 透视,透视后的图片大小
ret, dst = cv2.threshold(img,low,high,cv2.THRESH_**)
# 自适应阈值
# 计算每个像素点周围邻近区域的加权平均值获得阈值
dst = cv.adaptiveThreshold( src, maxValue, adaptiveMethod, thresholdType, blockSize, C )
# adaptiveMethod cv2.ADPTIVE_THRESH_MEAN_C 平均值
# cv2.ADAPTIVE_THRESH_GAUSSIAN_C 高斯加权,blockSize 指定领域大小,C 阈值在减去这个常数
# Otsu's 二值化
# 根据当前图像给出最佳的分割阈值,就是他会历遍所有阈值,然后找出最佳。
t2,otsu=cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
低通滤波LPF去除噪音,模糊图像,高通滤波 HPF 获取边缘
# 均值滤波
dst = cv2.blur( src, ksize, anchor, borderType )
# 方框滤波,ddepth 图像深度-1 ,normalize是否归一化,1 用均值与上面一样,0就使用像素值之和。
dst = cv2.boxFilter(src,ddepth,ksize,anchor,normalize,boderType)
# 高斯滤波,核是高斯分,宽和高要是奇数,cv2.getGaussianKernel()自己构建
dst = cv2.GaussianBlur( src, ksize, sigmaX, sigmaY, borderType )
r=cv2.GaussianBlur(o,(5,5),0,0)
# 中值滤波,用中间值,去除椒盐噪声,
dst = cv2.medianBlur( src, ksize)
# 双边滤波,考虑边缘和色彩信息,慢
dst = cv2.bilateralFilter( src, d, sigmaColor, sigmaSpace, borderType )
# 2D卷积,delta 修正值,在结果上在加这个值。
dst = cv2.filter2D( src, ddepth, kernel, anchor, delta, borderType )
kernel = np.ones((5,5),np.float32)/25
双边滤波在同时使用空间高斯权重和灰度值相似性高斯权重。空间高斯函
数确保只有邻近区域的像素对中心点有影响,灰度值相似性高斯函数确保只有
与中心像素灰度值相近的才会被用来做模糊运算。所以这种方法会确保边界不
会被模糊掉,因为边界处的灰度值变化比较大。
# 腐蚀,前景区域变小(白色)
dst = cv2.erode( src, kernel[, anchor[, iterations[, borderType[, borderValue]]]] )
# 膨胀,增加前景区域
dst = cv2.dilate( src, kernel[, anchor[, iterations[, borderType[, borderValue]]]])
dst = cv2.morphologyEx( src, op, kernel[, anchor[, iterations[, borderType[, borderValue]]]]] )
# 开运算,去除噪声,断开连接
# 闭运算,填充前景的小洞之类的
# 梯度 ,轮廓
# 礼帽,获得噪声信息,或比原始图像更亮的边缘信息
# 黑帽,获取图像内部的小孔,或前景色中的小黑点,或者比原始图像的边缘更暗的边缘部分。
结构化元素,构建一个椭圆形/圆形的核
retval = cv2.getStructuringElement( shape, ksize[, anchor]) cv2.MORPH_RECT cv2.MORPH_CROSS cv2.MORPH_ELLIPSE # Rectangular Kernel >>> cv2.getStructuringElement(cv2.MORPH_RECT,(5,5)) array([[1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1]], dtype=uint8) # Elliptical Kernel >>> cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5)) array([[0, 0, 1, 0, 0], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [0, 0, 1, 0, 0]], dtype=uint8) # Cross-shaped Kernel >>> cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5)) array([[0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [1, 1, 1, 1, 1], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0]], dtype=uint8)
就是求导,计算的是图像变化的速度
# Sobel dst = cv2.Sobel( src, ddepth, dx, dy[,ksize[, scale[, delta[, borderType]]]] ) dst = cv2.Scharr( src, ddepth, dx, dy[, scale[, delta[, borderType]]] ) # ddepth cv2.CV_64F 放置信息丢失再通过取绝对值将其映射为 cv2.CV_8U 八位图类型 # dx,dy x,y方向上的求导阶数,最大2,计算x 方向边缘(梯度) dx=1, dy=0, 只计算水平方向的边缘。 # ksize Sobel 核的大小,ksize=-1,会使用 3x3 的 Scharr 滤波器(更好) # scale 代表计算导数值时采用的缩放因子,默认1,没有缩放 # delta 代表加在目标图像dst 上的值,可选,默认0 # dst = cv2.convertScaleAbs( src [, alpha[, beta]] ) 位深转化函数,来取绝对值的 # or abs_sobel64f = np.absolute(sobelx64f) o = cv2.imread('5.jpg',0) Sobelx = cv2.Sobel(o,cv2.CV_64F,1,0) Sobely = cv2.Sobel(o,cv2.CV_64F,0,1) Sobelx = cv2.convertScaleAbs(Sobelx) Sobely = cv2.convertScaleAbs(Sobely) Sobelxy = cv2.addWeighted(Sobelx,0.5,Sobely,0.5,0) # 两个方向的叠加 Sobelxy11=cv2.Sobel(o,cv2.CV_64F,1,1) Sobelxy11=cv2.convertScaleAbs(Sobelxy11) # 只是两个方向的交点。 cv2.imshow("original",o) cv2.imshow("xy",Sobelxy) cv2.imshow("xy11",Sobelxy11) cv2.waitKey() cv2.destroyAllWindows() # 拉普拉斯算子,二阶导数算子,ksize 正的奇数,旋转不变性 dst = cv2.Laplacian( src, ddepth[, ksize[, scale[, delta[, borderType]]]] ) lap= cv2.Laplacian(o,cv2.CV_64F) lap = cv2.convertScaleAbs(lap)
Cany 边缘检测
edges = cv.Canny( image, threshold1, threshold2[, apertureSize[, L2gradient]]) ''' edges 计算得到的边缘图像 image 8位输入图像 threshold1,2 两个阈值 apertureSize Sobel算子孔径大小 L2gradient 计算图像梯度幅度的标志,Ture就用L2范数计算,默认False 使用L1范数 ''' def minth(a): minth = cv2.getTrackbarPos('minth','canny') maxth = cv2.getTrackbarPos('maxth','canny') edges = cv2.Canny(img,minth,maxth) cv2.imshow('canny',edges) img = cv2.imread('5.jpg',0) cv2.namedWindow('canny') cv2.createTrackbar('minth','canny',0,255,minth) cv2.createTrackbar('maxth','canny',0,255,minth) cv2.imshow('canny',img) cv2.waitKey(0) cv2.destroyAllWindows()
同一图像的不同分辨率的子图像。
# 向下采样,分辨率降低,dstsize 目标图像的大小 dst = cv2.pyrDown( src[, dstsize[, borderType]] ) # 向上采样 dst = cv2.pyrUp( src[, dstsize[, borderType]] ) # 拉普拉斯金字塔 Li = Gi - pyrUp(Gi + 1) o=cv2.imread('14.jpg') G0=o G1=cv2.pyrDown(G0) G2=cv2.pyrDown(G1) # 构建高斯金字塔 G3=cv2.pyrDown(G2) L0=G0-cv2.pyrUp(G1) L1=G1-cv2.pyrUp(G2) # 拉普拉斯金字塔 L2=G2-cv2.pyrUp(G3) RG0=L0+cv2.pyrUp(G1) # 其实就是上面式子的移项 print('G0.shape=',G0.shape) print('RG0.shape=',RG0.shape) result=RG0-G0 #将 RG0 和 G0 相减 # 获得的result 是一个数组 result=abs(result) print("原始图像 G0 与恢复图像 RG0 差值的绝对值和:",np.sum(result)) # 结果是0,表示两个图像是一样的。
图像金字塔的一个应用就是图像融合。
A = cv2.imread(r'D:\pycham\opencv3\you.jpg') B = cv2.imread(r'D:\pycham\opencv3\zuo.jpg') A = cv2.resize(A,(512,512),interpolation=cv2.INTER_AREA) # 各种尺寸问题。。。 B = cv2.resize(B,(512,512),interpolation=cv2.INTER_AREA) G = A.copy() gpA = [G] for i in range(6): # 构建高斯金字塔 G = cv2.pyrDown(G) gpA.append(G) G = B.copy() gpB = [G] # 一共七层 for i in range(6): G = cv2.pyrDown(G) gpB.append(G) lpA = [gpA[5]] for i in range(5,0,-1): GE = cv2.pyrUp(gpA[i]) L = cv2.subtract(gpA[i-1],GE) # 构建拉普拉斯金字塔 lpA.append(L) lpB = [gpB[5]] for i in range(5,0,-1): GE = cv2.pyrUp(gpB[i]) L = cv2.subtract(gpB[i-1],GE) lpB.append(L) LS = [] for la,lb in zip(lpA,lpB): rows,cols,dpt = la.shape print(la.shape,lb.shape) ls = np.hstack((la[:,0:cols//2], lb[:,cols//2:])) LS.append(ls) ls_ = LS[0] for i in range(1,6): ls_ = cv2.pyrUp(ls_) ls_ = cv2.add(ls_, LS[i]) real = np.hstack((A[:,:cols//2],B[:,cols//2:])) cv2.imshow('real',real) cv2.imshow('ls',ls_) cv2.waitKey(0) cv2.destroyAllWindows()
首先进行二值化或是canny 边缘检测。查找轮廓会修改原始图像,记得保存。要找的物体应该是白色的前景。
contours, hierarchy = cv2.findContours( image, mode, method) ''' contours 是一个列表,存储图像中的所有轮廓,每个轮廓都是一个numpy数组,包含边界的的(x,y)的坐标 hierarchy 轮廓的层次信息 [Next,Previous,First_Child,Parent],由mode 决定 mode 轮廓的提取方式:cv2.RETR_EXTERNAL:只检测外轮廓。 cv2.RETR_LIST:对检测到的轮廓不建立等级关系。 cv2.RETR_CCOMP:检索所有轮廓并将它们组织成两级层次结构。 cv2.RETR_TREE:建立一个等级树结构的轮廓。 method 轮廓的表达方式, cv2.CHAIN_APPROX_CONE 存储所有轮廓点,相邻两个点的像素位置差不超过1, cv2.CHAIN_APPROX_SIMPLE 压缩水平方向,垂直方向,对角线方向的元素, 只保留该方向的终点坐标,极端情况下,四个点来保存一个矩形的轮廓信息 ''' image=cv2.drawContours( image, contours, contourIdx, color [, thickness[, lineType[, hierarchy[, maxLevel[, offset]]]]] ) img = cv2.drawContours(img, contours, 3, (0,255,0), 3) # 说这个更有用是为啥呢。。。 retval = cv2.moments( array[, binaryImage] ) # 矩特征,binaryImage 将图像的非零值处理为0 # 返回矩特征 cx = int(M['m10']/M['m00']) cy = int(M['m01']/M['m00']) # 重心 M['m00'] 轮廓的面积 retval =cv2.contourArea(contour [, oriented] )) # 面积,oriented 表示轮廓是顺时针还是逆时针 retval = cv2.arcLength( curve, closed ) # 周长 hu = cv2.HuMoments( m ) # Hu 矩,图像经过缩放,平移旋转等操作后Hu 矩基本保持稳定,, retval = cv2.matchShapes( contour1, contour2, method, parameter ) # 形状匹配,匹配两个对象的Hu 矩 ret0 = cv2.matchShapes(cnt1,cnt1,1,0.0) # method 比较两个对象Hu 矩的方法。
retval = cv2.boundingRect( array ) # 矩形包围框,返回矩形边界左上角顶点坐标和矩形边界的宽度和高度 x,y,w,h = cv2.boundingRect( cnt) img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2) points =cv2.minAreaRect( points ) # 最小外包矩形框 返回(最小外接矩形的中心(x,y),(宽度,高度),旋转角度) points = np.int64(points) # 取整 points = cv2.boxPoints(points) # 将返回值转换成轮廓绘制参数的结构 image=cv2.drawContours(o,[points],0,(255,255,255),2) center, radius = cv2.minEnclosingCircle( points ) # 最小外包圆 retval = cv2.fitEllipse( points ) # 椭圆 中心点,轴长度,旋转角度 ellipse = cv2.fitEllipse(contours[0]) print("ellipse=",ellipse) cv2.ellipse(o,ellipse,(0,255,0),3) line = cv2.fitLine( points, distType, param, reps, aeps ) # 最优拟合直线 [vx,vy,x,y] = cv2.fitLine(contours[0], cv2.DIST_L2,0,0.01,0.01) lefty = int((-x*vy/vx) + y) # 说白了就是一个方向和一个点 righty = int(((cols-x)*vy/vx)+y) # 计算两个点,代值计算就行 cv2.line(o,(cols-1,righty),(0,lefty),(0,255,0),2) # 返回值是共线的归一化向量,和线上一点 retval, triangle = cv2.minEnclosingTriangle( points ) # 三角形 area,trgl = cv2.minEnclosingTriangle(contours[0]) for i in range(0, 3): cv2.line(o, tuple(trgl[i][0]), tuple(trgl[(i + 1) % 3][0]), (255,255,255), 2) # 逼近多边形 approxCurve = cv2.approxPolyDP( curve, epsilon, closed ) # 轮廓,精度,是否封闭 epsilon = 0.02*cv2.arcLength(contours[0],True) # 精度为0.02*周长 approx = cv2.approxPolyDP(contours[0],epsilon,True) adp=cv2.drawContours(adp,[approx],0,(0,0,255),2)
hull = cv2.convexHull( points[, clockwise[, returnPoints]] ) # hull 凸包角点,clockwise凸包角点按顺时针还是逆时针排序,returnPoints 真返回xy 轴坐标 否则返回轮廓的索引 convexityDefects = cv2.convexityDefects( contour, convexhull ) # 凸缺陷,需要convexHull returnPoints= False # 返回[起点,终点,轮廓上距离凸包最远的点,最远点到凸包的近似距离] hull = cv2.convexHull(cnt,returnPoints = False) # 需要索引 defects = cv2.convexityDefects(cnt,hull) # shape(23, 1, 4) for i in range(defects.shape[0]): s,e,f,d = defects[i,0] start = tuple(cnt[s][0]) # 得到的是索引,要再轮廓中选出来 end = tuple(cnt[e][0]) far = tuple(cnt[f][0]) cv2.line(o,start,end,[0,0,255],2) cv2.circle(o,far,5,[255,0,0],-1) retval = cv2.isContourConvex( contour ) # 检测一个曲线(轮廓类似的点集)是否是凸型的,,没什么大不了的。。(文档说的) retval = cv2.pointPolygonTest( contour, pt, measureDist ) # 点到轮廓的最短距离,mearsureDist False时返回相对位置,真返回距离,第三个参数设置为False可以大幅度提高速度 # 计算形状场景距离,使用距离作为形状比较的度量标准。 sd = cv2.createShapeContextDistanceExtractor() # 构造距离提取算子,, d1 = sd.computeDistance(cnt1,cnt1) print("与自身的距离 d1=", d1) 与自身的距离 d1= 0.0
# 宽高比 x,y,w,h = cv2.boundingRect(cnt) aspect_ratio = float(w)/h # Extent,轮廓面积与边界矩形面积的比。 area = cv2.contourArea(cnt) x,y,w,h = cv2.boundingRect(cnt) rect_area = w*h extent = float(area)/rect_area # Solidity,轮廓面积与凸包面积的比。 area = cv2.contourArea(cnt) hull = cv2.convexHull(cnt) hull_area = cv2.contourArea(hull) solidity = float(area)/hull_area # Equivalent Diameter,与轮廓面积相等的圆形的直径 area = cv2.contourArea(cnt) equi_diameter = np.sqrt(4*area/np.pi) # 掩模和像素点,获取某对象的掩膜图像和 对应的点。 idx = cv2.findNonZero( src ) # 非零元素的索引,返回(列号,行号) pixelpoints = np.transpose(np.nonzero(mask)) # (行号,列号) >>> np.nonzero(x) (array([0, 1, 2]), array([0, 1, 2])) >>> np.transpose(np.nonzero(x)) array([[0, 0], [1, 1], [2, 2]]) # 极值 min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(imgray,mask = mask) # 单通道,返回最大最小值和坐标 # 平均颜色和平均灰度,可以计算各通道的均值 mean_val = cv2.mean(im,mask = mask) # 四个极点 leftmost = tuple(cnt[cnt[:,:,0].argmin()][0]) # 轮廓点(y,x) rightmost = tuple(cnt[cnt[:,:,0].argmax()][0]) topmost = tuple(cnt[cnt[:,:,1].argmin()][0]) bottommost = tuple(cnt[cnt[:,:,1].argmax()][0])
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。