opencvpython 段力辉是哪本书_段力辉版本《OpenCV-Python 中文教程》学习

05c7dcae9a960c747d5baa6b0c643aa0.png

此书极好,值得借鉴学习,并且开源开放。Python在实现过程中,体现出来了非常强的优势,特别是结合Numpy来进行矩阵计算,有很多简化方法。这里将学习过程代码进行增编、添加后进行展示。

Python目前的缺点应该是缺乏一个像ImageWatch这样的工具,这将影响算法研究;另外Numpy的过度抽象,某种程度上也会造成障碍。

1、寻找指定色彩区域

Python的特色,在于Numpy的使用

import cv2

import numpy as np

src = cv2.imread("e:/template/tiantan.jpg")

hsv = cv2.cvtColor(src,cv2.COLOR_BGR2HSV)

lower_blue = np.array([100,43,46])

upper_blue = np.array([124,255,255])

mask = cv2.inRange(hsv,lower_blue,upper_blue)

res = cv2.bitwise_and(src,src,mask=mask)

cv2.imshow("hsv",hsv)

cv2.imshow("mask",mask)

cv2.imshow("res",res)

cv2.waitKey(0)

2、warpperspective 透视变化的python实现

ec06a60b435f5c1b0b5819cfba7710e1.png

import cv2

import numpy as np

src = cv2.imread("e:/template/steel03.jpg")

rows,cols,ch = src.shape

pts1 = np.float32([[122,0],[814,0],[22,540],[910,540]])

pts2 = np.float32([[0,0],[960,0],[0,540],[960,540]])

M = cv2.getPerspectiveTransform(pts1,pts2)

dst = cv2.warpPerspective(src,M,(cols,rows))

cv2.imshow("src",dst)

cv2.waitKey(0)

这里操作的核心,是一个np的矩阵。在C++中,使用Vector,可能会造成很多浪费。

3、自适应阈值

import cv2

import numpy as np

obj = cv2.imread("e:/template/pig.jpg",0)

ret,th1 = cv2.threshold(obj,100,255,cv2.THRESH_BINARY)

th2 = cv2.adaptiveThreshold(obj,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,2)

ret3,th3 = cv2.threshold(obj,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

cv2.imshow("th3",th3)

print(ret3)

cv2.waitKey()

当参数选择OTSU的时候,能够根据计算,自动算出下限。但是我认为这一点并没有什么特别的用途。

4、模糊处理

obj = cv2.imread("e:/template/pig.jpg",0)

blur= cv2.blur(obj,(3,3))

gaussBlur=cv2.GaussianBlur(obj,(3,3),0)

median = cv2.medianBlur(obj,5)

bilate = cv2.bilateralFilter(obj,0.75,0.75)

5、形态学变换

obj = cv2.imread("e:/template/pig.jpg",0)

opening = cv2.morphologyEx(obj,cv2.MORPH_OPEN,(7,7))

cv2.imshow("obj",obj)

cv2.imshow("opening",opening)

我喜欢这种写法,这将有长远影响。

6、梯度变化,包括1阶、2阶和混合的。

obj = cv2.imread("e:/template/pig.jpg",0)

laplacian = cv2.Laplacian(obj,cv2.CV_64F)

sobelx=cv2.Sobel(obj,cv2.CV_64F,1,0,ksize=5)

sobely=cv2.Sobel(obj,cv2.CV_64F,0,1,ksize=5)

a710c3eef46a1d2dc92aee4d47521837.png

7、梯度融合

曾经这段代码很神秘的,但是今日使用Python来写,就非常简单。可以看出,Python用来处理二维矩阵信息是很强的。

# Standard imports

import cv2

import numpy as np

A = cv2.imread("e:/template/apple.jpg")

B = cv2.imread("e:/template/orange.jpg")

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(rows,cols)

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("ls_",ls_)

cv2.imshow("real",real)

cv2.waitKey()

878c8100db5ac102209012ea4a459941.png

8、轮廓寻找

import cv2

import numpy as np

src = cv2.imread("e:/template/rectangle.jpg")

gray = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)

ret,thresh = cv2.threshold(gray,127,255,0)

contours,hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

print(contours)

src = cv2.drawContours(src,contours,-1,(0,255,0),3)

cv2.imshow("src",src)

cv2.waitKey()

这里,使用cv2.CHAIN_APPROX_NONE或者不同的参数的话,会获得不同的轮廓结果。这对于我现有的轮廓分析研究,也是有帮助的。

9、轮廓的最小? ?接圆和最大内切圆

外接圆比较简单

(x,y),radius = cv2.minEnclosingCircle(contours[0])

center = (int(x),int(y))

radius = int(radius)

src = cv2.circle(src,center,radius,(0,255,0),2)

80effc76ed0a915e56b67ef6d44517bb.png

注意它这里的表示方法。内切圆则采用特殊方法。

# Get the contours

contours, _ = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)

# Calculate the distances to the contour

raw_dist = np.empty(thresh.shape, dtype=np.float32)

for i in range(src.shape[0]):

for j in range(src.shape[1]):

raw_dist[i,j] = cv.pointPolygonTest(contours[0], (j,i), True)

minVal, maxVal, _, maxDistPt = cv.minMaxLoc(raw_dist)

minVal = abs(minVal)

maxVal = abs(maxVal)

# Depicting the  distances graphically

drawing = np.zeros((src.shape[0], src.shape[1], 3), dtype=np.uint8)

for i in range(src.shape[0]):

for j in range(src.shape[1]):

if raw_dist[i,j] 

drawing[i,j,0] = 255 - abs(raw_dist[i,j]) * 255 / minVal

elif raw_dist[i,j] > 0:

drawing[i,j,2] = 255 - raw_dist[i,j] * 255 / maxVal

else:

drawing[i,j,0] = 255

drawing[i,j,1] = 255

drawing[i,j,2] = 255

cv.circle(drawing,maxDistPt,int(maxVal),(255,255,255))

cv.imshow(‘Source‘, src)

cv.imshow(‘Distance and inscribed circle‘, drawing)

cv.waitKey()

c7fd8aa36626c05f35d71b3f8c32d4d5.png

最大内接圆则复杂许多。

10、寻找轮廓的极点

efcadbb4e3e3641a1297efb47b06b598.png

contours, _  = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

cnt = contours[0]

leftmost = tuple(cnt[cnt[:,:,0].argmin()][0])

rightmost= tuple(cnt[cnt[:,:,0].argmax()][0])

topmost  = tuple(cnt[cnt[:,:,1].argmin()][0])

bottommost=tuple(cnt[cnt[:,:,1].argmax()][0])

cv2.circle(src,leftmost,5,(0,255,0))

cv2.circle(src,rightmost,5,(0,255,255))

cv2.circle(src,topmost,5,(255,255,0))

cv2.circle(src,bottommost,5,(255,0,0))

cv2.imshow("src",src)

这是一种很好的方法,能够直接找出轮廓的各方向边界。

11 模板匹配

src = cv.imread("e:/template/lena.jpg",0)

template = cv.imread("e:/template/lenaface.jpg",0)

w,h = template.shape

res = cv.matchTemplate(src,template,cv.TM_CCOEFF)

min_val,max_val,min_loc,max_loc = cv.minMaxLoc(res)

cv.rectangle(src,max_loc,(max_loc[0]+w,max_loc[1]+h),(0,0,255),2)

cv.imshow("template",template)

cv.imshow("src",src)

cv.waitKey()

30759b19d42828fbac287396625a98fa.png

我想体现的是python它的写法有很大不同。

src = cv.imread("e:/template/coin.jpg")

gray = cv.cvtColor(src,cv.COLOR_BGR2GRAY)

template = cv.imread("e:/template/coincut.jpg",0)

w,h = template.shape

res = cv.matchTemplate(gray,template,cv.TM_CCOEFF_NORMED)

threshold =0.4

loc = np.where(res>=threshold)

print(loc)

for pt in zip(*loc[::1]):

cv.rectangle(src,pt,(pt[0]+w,pt[1]+h),(0,0,255),2)

cv.imshow("template",template)

cv.imshow("src",src)

cv.waitKey()

结合使用阈值,可以实现多目标匹配。

# Standard imports

import cv2 as cv

import numpy as np

src = cv.imread("e:/template/coin.jpg")

gray = cv.cvtColor(src,cv.COLOR_BGR2GRAY)

template = cv.imread("e:/template/coincut.jpg",0)

w,h = template.shape

res = cv.matchTemplate(gray,template,cv.TM_CCOEFF_NORMED)

threshold =0.6

loc = np.where(res>=threshold)

print(loc)

for pt in zip(*loc[::-1]):#排序方法为height width

print(pt)

cv.rectangle(src,pt,(pt[0]+w,pt[1]+h),(0,0,255),2)

cv.imshow("template",template)

cv.imshow("src",src)

cv.waitKey()

特别需要注意其排序方法。但是这里的阈值选择,也是超参数类型的。

57cc3b0d08ddeb95e3c9ab5de0ab02a4.png

12 HoughCircle

src = cv.imread("e:/template/circle.jpg",0)

src = cv.medianBlur(src,5)

cimg = cv.cvtColor(src,cv.COLOR_GRAY2BGR)

circles = cv.HoughCircles(src,cv.HOUGH_GRADIENT,1,20,param1=50,param2=30,minRadius=0,maxRadius=0)

circles = np.uint16(np.around(circles))

for i in circles[0,:]:

cv.circle(cimg,(i[0],i[1]),i[2],(0,255,0),2)

cv.circle(cimg,(i[0],i[1]),2,(0,0,255),3)

cv.imshow("src",cimg)

cv.waitKey()

2d7bc22c4a3789cb3621e81ceb2adfa7.png

13 风水岭算法

# Standard imports

import cv2 as cv

import numpy as np

src = cv.imread("e:/template/water_coins.jpg")

gray =cv.cvtColor(src,cv.COLOR_BGR2GRAY)

_,thresh = cv.threshold(gray,0,255,cv.THRESH_BINARY_INV+cv.THRESH_OTSU)

kernel = np.ones((3,3),np.uint8)

opening = cv.morphologyEx(thresh,cv.MORPH_OPEN,kernel,iterations=2)

sur_bg = cv.dilate(opening,kernel)

dist_transform = cv.distanceTransform(opening,1,5)

_,sur_fg=cv.threshold(dist_transform,0.7*dist_transform.max(),255,0)

sur_fg = np.uint8(sur_fg)

unknow = cv.subtract(sur_bg,sur_fg)

_,markers1 = cv.connectedComponents(sur_fg)

markers = markers1+1

markers[unknow ==255] = 0

markers3 = cv.watershed(src,markers)

src[markers3 == -1] = [255,0,0]

cv.imshow("src",src)

cv.waitKey()

e9f4cf35501f4f90a12ea5dcde13d838.png

这个结果,具有参考价值。

来自为知笔记(Wiz)

段力辉版本《OpenCV-Python 中文教程》学习

原文:https://www.cnblogs.com/jsxyhelu/p/12769770.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值