日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

【Python5】图像操作,数字验证码识别,图像拼接/保存器

發布時間:2024/4/24 python 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Python5】图像操作,数字验证码识别,图像拼接/保存器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 1.安裝
  • 2.畫圖
  • 3.幾何變換
    • 3.1 位計算
    • 3.2 遮擋
    • 3.3 通道切分合并
    • 3.4 金字塔
    • 3.5 縮放
    • 3.6 平移
    • 3.7 旋轉
    • 3.8 仿射變換
    • 3.9 透視變換
  • 4.形態學
  • 5.模糊(平滑)
  • 6.色彩空間轉換
  • 7.二值化
  • 8.圖像梯度
  • 9.canny邊緣檢測
  • 10.視頻操作
    • 10.1 讀取攝像頭視頻
    • 10.2 讀取視頻文件
    • 10.3 視頻寫入
    • 10.4 視頻提取指定顏色
  • 11.直方圖
  • 12.模板匹配
  • 13.直線/圓/輪廓檢測
  • 14.人臉檢測
  • 15.數字驗證碼識別
  • 16.圖像拼接/保存器


1.安裝

pip install opencv-python,下面第一行是擴展模塊,第二行是OCR。

附:如果cv.不提醒代碼提示功能,ctrl+左鍵就可以查看源碼,先pip上圖前兩行:
?xxx\Anaconda3\Lib\site-packages\cv2\__init__.py中刪除原來程序,寫入下段程序:

import sys import os import importlib os.environ["PATH"] += os.pathsep + os.path.dirname(os.path.realpath(__file__)) from .cv2 import * globals().update(importlib.import_module('cv2.cv2').__dict__)

2.畫圖

import numpy as np import cv2 import matplotlib.pyplot as plt def show(image):plt.imshow(image)plt.axis('off')plt.show() image = np.zeros((300,300,3),dtype='uint8') show(image)

green = (0,255,0) # opencv:RGB cv2.line(image,(0,0),(300,300),green) # 左上角(0,0),右下角(300,300) show(image)

blue = (0,0,255) cv2.line (image,(300,0),(150,150),blue,5) # 這里5為粗細,默認為1 show(image)

red = (255,0,0) cv2.rectangle(image,(10,10),(60,60),red,2) # 2改則為-1則為紅色實心填充矩形 show(image)

(cx,cy)=image.shape[1]//2,image.shape[0]//2 # 寬/2,高/2,則為圓心 white = (255,255,255) for r in range(0,151,15): #0到150,151取不到,步長15cv2.circle(image,(cx,cy),r,white,2) show(image)

image = np.zeros((300,300,3),dtype='uint8') for i in range(10):radius=np.random.randint(5,20) # 半徑取值color=np.random.randint(0,255,size=(3,)).tolist() # tolist()變列表[],顏色取值pt=np.random.randint(0,300,size=(2,)) # 圓心取值cv2.circle(image,tuple(pt),radius,color,-1) # 畫圖 show(image)

image = cv2.imread('C:/Users/yuta/Desktop/img3/20190720072950_000256_cc8cdaa6430.JPG') image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) show(image)

3.幾何變換

# -*- encoding: utf-8 -*- # -*- coding=GBK -*- import cv2 import os import numpy as np import matplotlib as plt import matplotlib.pyplot as plt for imgname in os.listdir("C:/Users/yuta/Desktop/img3"):imgpath = "C:/Users/yuta/Desktop/img3/"+imgnameprint(imgpath)src = cv2.imread(imgpath)a = cv2.flip(src,1) # 水平翻轉b = cv2.flip(src, 0) # 垂直翻轉c = cv2.flip(src, -1) # 水平+垂直d = src[200:,150:-150] # 剪裁,x方向:200到最后,y方向:150到 下往上150cv2.imshow('input image', b)cv2.waitKey(0) M = np.ones(src.shape,dtype='uint8')*100 # 生成和圖片形狀相同并且全為100的數據e = cv2.add(src,M) # 所有像素加100,往255白發展,調亮度f = cv2.subtract(src, M)cv2.imshow('input image', e)cv2.waitKey(0) # 圖像加法 print(cv2.add(np.unit8([200]),np.uint8([100]))) #輸出[[255]],圖像范圍0-255,300也轉為255 # 普通加法 print(np.unit8([200])+np.uint8([100])) #[44],unit8也0-255,加到255重新記為1 # 圖像減法 print(cv2.subtract(np.uint8([50]),np.uint8([100]))) #輸出[[0]],圖像范圍0-255,-50轉為0 # 普通減法 print(np.uint8([50])-np.unit8([100])) #輸出[206]

3.1 位計算

rectangle = np.zeros((300,300,3),dtype='uint8')white = (255,255,255)cv2.rectangle(rectangle,(25,25),(275,275),white,-1) # (25,25)初始,(275,275)終止,-1填充cv2.imshow('input image', rectangle)cv2.waitKey(0)


與:有0為0,或:有1為1,異或:同0

circle = np.zeros((300,300,3),dtype='uint8')white = (255, 255, 255)cv2.circle(circle,(150,150),150,white,-1) # (150,150)圓心,150半徑cv2.imshow('input image', circle)cv2.waitKey(0)

g = cv2.bitwise_and(rectangle,circle) # AND與,有0變0即有黑變黑h = cv2.bitwise_or(rectangle,circle) # OR或,有白變白i = cv2.bitwise_xor(rectangle,circle) # XOR異或,黑白變白,黑黑和白白變黑cv2.imshow('input image', g)cv2.waitKey(0)

3.2 遮擋

mask = np.zeros(src.shape,dtype='uint8') white = (255,255,255)cv2.rectangle(mask,(50,50),(250,350),white,-1) # 創建黑色遮擋cv2.imshow('input image', mask)cv2.waitKey(0)

masked = cv2.bitwise_and(src, mask)cv2.imshow('input image', masked)cv2.waitKey(0)

3.3 通道切分合并

(R,G,B) = cv2.split(src) #cv2.imshow('input image',G),分開就是三張單通道黑白,print(R.shape)merged = cv2.merge([R,G,B]) cv2.imshow('input image', merged) #產生彩色原圖cv2.waitKey(0)

3.4 金字塔


imgpath = "C:/Users/yuta/Desktop/img3/20190720072950_000256_cc8cdaa64390.JPG" src1 = cv2.imread(imgpath) for i in range(3):src1=cv2.pyrDown(src1) #不能j=print(src1.shape)cv2.imshow('input image',src1) # 生成3張大小不同圖cv2.waitKey(0) down_image1 = cv2.pyrDown(src1) down_image2 = cv2.pyrDown(down_image1) up_image = cv2.pyrUp(down_image2) laplacian = down_image1-up_imagecv2.imshow('input image',laplacian) cv2.waitKey(0)

3.5 縮放






3.6 平移



3.7 旋轉


3.8 仿射變換



3.9 透視變換





4.形態學

腐,膨。開,閉,開閉。白帽,黑帽

kernel1=cv2.getStructuringElement(cv2.MORPH_RECT,(5,5)) kernel2=cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5)) kernel3=cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5)) erosion = cv2.erode(src1,kernel1) # 腐蝕cv2.imshow('input image',erosion) cv2.waitKey(0)

for i in range(3):erosion = cv2.erode(src1, kernel1,iterations=i+1)cv2.imshow('input image', erosion) #三次腐蝕顏色越來越深cv2.waitKey(0) for i in range(3):dilation= cv2.dilate(src1, kernel1,iterations=i+1) #膨脹dilate,取得是局部最大值cv2.imshow('input image', dilation) #三次膨脹顏色越來越白cv2.waitKey(0) kernel1=cv2.getStructuringElement(cv2.MORPH_RECT,(5,5)) opening = cv2.morphologyEx(src1,cv2.MORPH_OPEN,kernel1) # 開運算:先腐蝕后膨脹 closing = cv2.morphologyEx(src1,cv2.MORPH_CLOSE,kernel1) # 閉運算:先膨脹后腐蝕cv2.imshow('input image', opening) cv2.waitKey(0) opening = cv2.morphologyEx(src1,cv2.MORPH_OPEN,kernel1) # 開閉運算 closing = cv2.morphologyEx(opening,cv2.MORPH_CLOSE,kernel1) cv2.imshow('input image', closing) cv2.waitKey(0)

gradient = cv2.morphologyEx(src1,cv2.MORPH_GRADIENT,kernel1)cv2.imshow('input image', gradient) cv2.waitKey(0)



blackhat = cv2.morphologyEx(src1,cv2.MORPH_BLACKHAT,kernel1)cv2.imshow('input image', blackhat) cv2.waitKey(0)

5.模糊(平滑)

kernelsizes = [(3,3),(9,9),(15,15)] # 越大越模糊 plt.figure(figsize = (15,15)) src1 = cv2.cvtColor(src1, cv2.COLOR_BGR2RGB) for i,kernel in enumerate (kernelsizes):plt.subplot(1,3,i+1)blur = cv2.blur(src1,kernel) # 平均平滑plt.axis('off')plt.title('Blurred'+str(kernel)) # 設置標題plt.imshow(blur) plt.show()


kernelsizes = [(3,3),(9,9),(15,15)] plt.figure(figsize = (15,15)) src1 = cv2.cvtColor(src1, cv2.COLOR_BGR2RGB) for i,kernel in enumerate (kernelsizes):plt.subplot(1,3,i+1)blur = cv2.GaussianBlur(src1,kernel,0) # 0為標準差plt.axis('off')plt.title('Blurred'+str(kernel))plt.imshow(blur) plt.show()


plt.figure(figsize = (15,15)) src1 = cv2.cvtColor(src1, cv2.COLOR_BGR2RGB) for i,kernel in enumerate ((3,9,15)):plt.subplot(1,3,i+1)blur = cv2.medianBlur(src1,kernel)plt.axis('off')plt.title('Blurred'+str(kernel))plt.imshow(blur) plt.show()


params = [(11,21,7),(11,41,21),(15,75,75)] plt.figure(figsize = (15,15)) src1 = cv2.cvtColor(src1, cv2.COLOR_BGR2RGB) for i,(diameter,sigmaColor,sigmaSpace) in enumerate (params): # 鄰域直徑,灰度值相似性高斯濾波函數標準差,空間高斯函數標準差plt.subplot(1,3,i+1)blur = cv2.bilateralFilter(src1,diameter,sigmaColor,sigmaSpace) #平均平滑plt.axis('off')plt.title('Blurred'+str((diameter,sigmaColor,sigmaSpace)))plt.imshow(blur) plt.show()

6.色彩空間轉換

(B,G,R) = cv2.split(src1) zeros = np.zeros(src1.shape[:2],dtype='uint8') #src1.shape[:2]和src1寬高一樣cv2.imshow('input image', cv2.merge([zeros,G,zeros])) cv2.waitKey(0)



hsv = cv2.cvtColor(src1,cv2.COLOR_BGR2HSV) zeros = np.zeros(src1.shape[:2],dtype='uint8') for(name,chan) in zip(('H','S','V'),cv2.split(hsv)):cv2.imshow(name,chan)cv2.waitKey(0) cv2.destroyAllWindows()


lab = cv2.cvtColor(src1,cv2.COLOR_BGR2LAB) zeros = np.zeros(src1.shape[:2],dtype='uint8') for (name,chan) in zip(('L','A','B'),cv2.split(lab)):cv2.imshow(name,chan) #縮進 cv2.waitKey(0)


gray = cv2.cvtColor(src1,cv2.COLOR_BGR2GRAY)cv2.imshow('original',src1) cv2.imshow('gray',gray) cv2.waitKey(0)

7.二值化

gray =cv2.cvtColor(src1,cv2.COLOR_BGR2GRAY) plt.imshow(gray,'gray') # plt顯示要加‘gray’ plt.axis('off') plt.show()

ret1,thresh1 = cv2.threshold(gray,127,255,cv2.THRESH_BINARY) #127閾值 ret2,thresh2 = cv2.threshold(gray,127,255,cv2.THRESH_BINARY_INV) ret3,thresh3 = cv2.threshold(gray,127,255,cv2.THRESH_TRUNC) ret4,thresh4 = cv2.threshold(gray,127,255,cv2.THRESH_TOZERO) ret5,thresh5 = cv2.threshold(gray,127,125,cv2.THRESH_TOZERO_INV) titles = ['original','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV'] src1 = [gray,thresh1,thresh2,thresh3,thresh4,thresh5] plt.figure(figsize=(15,5)) for i in range(6):plt.subplot(2,3,i+1)plt.imshow(src1[i],'gray')plt.title(titles[i])plt.axis('off') plt.show()

#下面為遮擋,白色部分顯示原圖即提取。將閾值調小顯示更好,但太小黑色背景會有白色噪聲點 cv2.imshow('mask',cv2.bitwise_and(src1,src1,mask=thresh1)) cv2.waitKey(0)

ret1,thresh1 = cv2.threshold(gray,0,255,cv2.THRESH_BINARY | cv2.THRESH_OTSU) # 0閾值自動 ret2,thresh2 = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU) print('ret1',ret1) print('ret2',ret2)plt.imshow(thresh1,'gray') plt.axis('off') plt.show() plt.imshow(thresh2,'gray') plt.axis('off') plt.show()



image = cv2.cvtColor(src1,cv2.COLOR_BGR2GRAY) # 變灰度圖 image = cv2.medianBlur(image,5) # 中值濾波 ret,th1 = cv2.threshold(image,127,255,cv2.THRESH_BINARY) # 普通二值化 th2 = cv2.adaptiveThreshold(image,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,11,3) # 平均值閾值 th3 = cv2.adaptiveThreshold(image,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,3) # 高斯閾值titles = ['original','Global','Thresholding','adaptive Mean Thresholding','Adaptive Gaussian Thresholding'] images = [image,th1,th2,th3] plt.figure(figsize=(10,5)) for i in range(4):plt.subplot(2,2,i+1)plt.imshow(images[i],'gray')plt.axis('off')plt.title(titles[i]) plt.show()

8.圖像梯度



def gradient(image):image = cv2.cvtColor(image,cv2.COLOR_RGB2GRAY)laplacian = cv2.Laplacian(image,cv2.CV_64F) #cv2.CV_64F輸出圖像的深度(數據類型),64位float類型,因為梯度可能是正或負sobelx = cv2.Sobel(image,cv2.CV_64F,1,0,ksize=3) #1,0表示在X方向求一階導數,最大可以求2階導數sobely = cv2.Sobel(image,cv2.CV_64F,0,1,ksize=3) #0,1表示在y方向求一階導數,最大可以求2階導數titles = ['Original','Laplacian','SobelX','SobelY']images = [image,laplacian,sobelx,sobely]plt.figure(figsize=(10,5))for i in range(4):plt.subplot(2,2,i+1)plt.imshow(images[i],'gray')plt.title(titles[i])plt.axis('off')plt.show() gradient(src1)

9.canny邊緣檢測




def edge_detection(image,minVal=100,maxVal=200):image = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)edges = cv2.Canny(image,minVal,maxVal)plt.imshow(edges,'gray')plt.axis('off')plt.show() edge_detection(src1)

image = cv2.cvtColor(src1,cv2.COLOR_BGR2GRAY) image = cv2.GaussianBlur(image,(3,3),0) Value = [(10,150),(100,200),(180,230)] plt.figure(figsize=(20,5)) for i,(minVal,maxVal) in enumerate(Value):plt.subplot(1,3,i+1)edges = cv2.Canny(image,minVal,maxVal)edges= cv2.GaussianBlur(edges,(3,3),0)plt.imshow(edges,'gray')plt.title(str((minVal,maxVal)))plt.axis('off') plt.show()

def auto_canny(image,sigma=0.33):v=np.median(image)lower = int(max(0,(1.0-sigma)*v))upper = int(min(255,(1.0+sigma)*v))edged = cv2.Canny(image,lower,upper)print(lower,upper)return edged edges = auto_canny(src1) edges = cv2.GaussianBlur(edges,(3,3),0) plt.imshow(edges,'gray') plt.axis('off') plt.show()

10.視頻操作

10.1 讀取攝像頭視頻

cap = cv2.VideoCapture(0) while(True):ret,frame = cap.read() #ret讀取成功True或失敗False,frame讀取到的圖像內容,讀取一幀數據gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)cv2.imshow('frame',gray) #或('frame',frame)if cv2.waitKey(1) & 0xff == ord('q'): #waitKey功能是不斷刷新圖像,單位ms,返回值是當前鍵盤按鍵值。ord返回對應的ASCII數值break cap.release() cv2.destroyAllWindows()

10.2 讀取視頻文件


cap = cv2.VideoCapture('D:/KK_Movies/kk 2019-09-21 11-29-04.mp4') fps = cap.get(cv2.CAP_PROP_FPS) # 視頻每秒傳輸幀數 frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) # 視頻圖像寬度 frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) # 視頻圖像長度 print(fps) print(frame_width) print(frame_height)while(True):ret,frame = cap.read() if ret != True:breakcv2.imshow('frame',frame)if cv2.waitKey(25)&0xff == ord('q'): # 25變大視頻播放變慢break cap.release() cv2.destroyAllWindows()

10.3 視頻寫入

cap = cv2.VideoCapture('D:/KK_Movies/kk 2019-09-21 11-29-04.mp4') fps = cap.get(cv2.CAP_PROP_FPS) frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) print(fps) print(frame_width) print(frame_height)fourcc = cv2.VideoWriter_fourcc(*'XVID') out = cv2.VideoWriter('C:/Users/yuta/Desktop/333/1.avi',fourcc,fps,(frame_width,frame_height)) while(True):ret,frame = cap.read()if ret == True:#frame = cv2.flip(frame,1)out.write(frame)cv2.imshow('frame',frame)if cv2.waitKey(25)&0xff == ord('q'):breakelse:break out.release() cap.release() cv2.destroyAllWindows()

10.4 視頻提取指定顏色

# 色彩空間轉為hsv和inrange函數從視頻中提取指定顏色 # 并將其置為白,其余置為黑,實現跟蹤某一顏色 import cv2 as cv import numpy as np def nextrace_object_demo():capture = cv.VideoCapture("E:/1.mp4")#導入視頻while True:ret, frame = capture.read()if ret == False:breakhsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)#上一行將frame視頻一幀圖轉為hsv色彩空間 #如下設置綠色的范圍,跟蹤視頻中的綠色,調節圖像顏色信息(H)、飽和度(S)、亮度(V)區間lower_hsv = np.array([35, 43, 46])#設置過濾的綠色的低值,可查看下表upper_hsv = np.array([77, 255, 255])#設置過濾的綠色的高值mask = cv.inRange(hsv, lowerb=lower_hsv, upperb=upper_hsv)#用inRange函數提取指定顏色范圍,這里對hsv來處理,得到二值圖#dst = cv.bitwise_and(frame,frame,mask=mask)#cv.imshow("mask",dst)cv.imshow("video", frame)cv.imshow("mask", mask)if cv.waitKey(50) & 0xFF == ord('q'):breaknextrace_object_demo() cv.waitKey(0) cv.destroyAllWindows()


下圖為#兩行用bitwise_and輸出

可以通過下表對應顏色的數值過濾其他顏色,HSV顏色對應RGB的分量范圍:

import cv2 as cv import numpy as np src = cv.imread("E:/images/demo.JPG") cv.namedWindow("input image", cv.WINDOW_NORMAL) cv.imshow('input image',src) # 通道分離,輸出三個單通道圖片 b, g, r = cv.split(src) # 將彩色圖像分割成3個通道 cv.imshow("blue", b) cv.imshow("green", g) cv.imshow("red", r)# 通道合并 src = cv.merge([b, g, r]) cv.imshow("merge image", src)# 修改某個通道的值,[:, :, 0]為第一個通道,[:, :, 1]為第二個通道 src[:, :, 2] = 100 cv.imshow("changed image", src)cv.waitKey(0) cv.destroyAllWindows()

11.直方圖

# -*- coding: utf-8 -*- import cv2 as cv import matplotlib.pyplot as plt def plot_demo(image): #x軸為像素點取值,y軸為像素點個數plt.figure(figsize = (5,3))plt.hist(image.ravel(), 256, [0, 256])#image.ravel()將圖像展開,256為bins數量,[0, 256]為范圍plt.ylim([0, 20000])plt.title('123')plt.show() def image_hist(image):color = ('blue', 'green', 'red')for i, color in enumerate(color):# 計算出直方圖,calcHist(images, channels, mask, histSize(有多少個bin), ranges)hist = cv.calcHist(image, [i], None, [256], [0, 256])print(hist.shape)plt.plot(hist, color=color)plt.xlim([0, 256])plt.show()#上面為繪制圖片直方圖,下面是直方圖應用 def equalHist_demo(image):gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY) #下行 `全局`直方圖均衡化,提升對比度(默認提升),只能是灰度圖像用于增強圖像對比度,即黑的更黑,白的更白dst = cv.equalizeHist(gray)cv.imshow("equalHist_demo", dst) #下行`局部`直方圖均衡化,自定義,clipLimit是對比度的大小,tileGridSize是每次處理塊的大小clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))clahe_dst = clahe.apply(gray)cv.imshow("clahe", clahe_dst)src = cv.imread("E:\images/demo.jpg") cv.imshow("yuantu", src)plot_demo(src) image_hist(src) equalHist_demo(src)cv.waitKey(0) cv.destroyAllWindows()

12.模板匹配

# -*- coding: utf-8 -*- import cv2 as cv import numpy as np # 模板匹配,就是在整個圖像區域發現與給定子圖像匹配的小塊區域, # 需要模板圖像T和待檢測圖像-源圖像S # 工作方法:在待檢測的圖像上,從左到右,從上倒下計算模板圖像與重疊子圖像匹配度, # 匹配度越大,兩者相同的可能性越大。 def template_demo():tpl = cv.imread("E:\images/4.jpg")target = cv.imread("E:\images/3.jpg")cv.imshow("template", tpl)cv.imshow("target", target)methods = [cv.TM_SQDIFF_NORMED, cv.TM_CCORR_NORMED, cv.TM_CCOEFF_NORMED] #上行參數三種模板匹配方法th, tw = tpl.shape[:2] #模板的高寬for md in methods:print(md)result = cv.matchTemplate(target, tpl, md) # 得到匹配結果min_val, max_val, min_loc, max_loc = cv.minMaxLoc(result)if md == cv.TM_SQDIFF_NORMED: #cv.TM_SQDIFF_NORMED最小時最相似,其他最大時最相似tl = min_locelse:tl = max_locbr = (tl[0] + tw, tl[1] + th) # br為右下角坐標=tl為左上角坐標+寬高cv.rectangle(target, tl, br, (0, 0, 255), 2) # (0, 0, 255)為紅色,2為線寬,繪到target上。cv.imshow("match-"+np.str(md), target)template_demo()cv.waitKey(0) cv.destroyAllWindows()

13.直線/圓/輪廓檢測

霍夫變換:目的是通過投票程序在特定類型的形狀內找到對象的不完美實例。這個投票程序是在一個參數空間中進行的,在這個參數空間中,候選對象被當作所謂的累加器空間中的局部最大值來獲得。Hough變換主要優點是能容忍特征邊界描述中的間隙,并且相對不受圖像噪聲的影響。

霍夫直線變換:1.Hough Line Transform用來做直線檢測
2.前提條件:邊緣檢測已完成
3.平面空間到極坐標空間轉換

# -*- coding: utf-8 -*- import cv2 as cv import numpy as np def line_detection(image):gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)edges = cv.Canny(gray, 50, 150, apertureSize=3)#Canny做梯度窗口大小apertureSize=3#cv2.HoughLines()返回值就是(ρ,θ)。ρ 的單位是像素,θ 的單位是弧度。#這個函數的第一個參數是一個二值化圖像,所以在進行霍夫變換之前要首先進行二值化,或者進行 Canny邊緣檢測。#第二和第三個值分別代表 ρ 和 θ 的精確度。第四個參數是閾值,只有累加其中的值高于閾值時才被認為是一條直線,#也可以把它看成能檢測到的直線的最短長度(以像素點為單位)。lines = cv.HoughLines(edges, 1, np.pi/180, 80)#'NoneType' object is not iterable:沒有檢測到直線,lines為空,進入for循環發生錯誤:調整上面第四個參數。for line in lines:print(type(lines))rho, theta = line[0]a = np.cos(theta)b = np.sin(theta)x0 = a * rhoy0 = b * rhox1 = int(x0 + 1000*(-b))y1 = int(y0 + 1000*(a))x2 = int(x0 - 1000*(-b))y2 = int(y0 - 1000*(a))cv.line(image, (x1, y1), (x2, y2), (0, 0, 255), 2) # 2為像素寬cv.imshow("line_detection", image)def line_detection_possible_demo(image):gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)edges = cv.Canny(gray, 50, 150, apertureSize=3)lines = cv.HoughLinesP(edges, 1, np.pi / 180, 80, minLineLength=50, maxLineGap=10)for x1, y1, x2, y2 in lines[0]:cv.line(image, (x1, y1), (x2, y2), (255, 0, 0), 2)cv.imshow('line_detection_possible_demo', image)def detection_circles_demo(image):dst = cv.pyrMeanShiftFiltering(image, 10, 100)#均值遷移,sp,sr為空間域核與像素范圍域核半徑gray = cv.cvtColor(dst, cv.COLOR_BGR2GRAY)circles = cv.HoughCircles(gray, cv.HOUGH_GRADIENT, 1, 20, param1=40, param2=30, minRadius=0, maxRadius=0)#上面1為dp步長,20為最小距離,圓心小于20為一個圓。circles = np.uint16(np.around(circles))print(circles.shape)for i in circles[0,:]: # draw the outer circlecv.circle(image, (i[0], i[1]), i[2], (0, 255, 0), 2) # draw the center of the circlecv.circle(image, (i[0], i[1]), 2, (255, 0, 0), 3) # 畫圓心cv.imshow('detected circles', image)def main():src = cv.imread("E:\images/dave.png")cv.imshow("demo",src)line_detection(src)line_detection_possible_demo(src)img = cv.imread("E:\images/circle.png")detection_circles_demo(img)cv.waitKey(0)cv.destroyAllWindows()if __name__ == '__main__':main()

14.人臉檢測

haar和lap數據:https://github.com/opencv/opencv/tree/master/data
win10下載子目錄見文章:https://blog.csdn.net/weixin_43435675/article/details/88201615

import cv2 as cvdef face_detection(image):gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)face_detector = cv.CascadeClassifier(r"E:\images/1/haarcascade_frontalface_alt_tree.xml")# 在Python中\是轉義符,\u表示其后是UNICODE編碼,因此\User在這里會報錯,在字符串前面加個r表示就可以了faces = face_detector.detectMultiScale(gray, 1.02, 2)# 多個尺度檢測,向上或者向下是原來1.02倍,# 第二個參數是移動距離,第三個參數是識別度,越大識別讀越高# faces就是幾個候選矩形框for x, y, w, h in faces: # 取出這四個值cv.rectangle(image, (x, y), (x+w, y+h), (0, 0, 255), 2) # 繪制在圖上cv.imshow("result", image)def main():src = cv.imread("E:\images/lena.jpg")cv.imshow("input image", src)face_detection(src)# # 視頻檢測# capture = cv.VideoCapture(0)# while True:# ret, frame = capture.read()# frame = cv.flip(frame, 1)# face_detection(frame)# c = cv.waitKey(10)# if c == 27: #c == 27 時是用esc關閉的# breakcv.waitKey(0)cv.destroyAllWindows() # 關閉所有窗口if __name__ == '__main__':main()

15.數字驗證碼識別

pip install pytesseract
錯誤:pytesseract.pytesseract.TesseractNotFoundError: tesseract is not installed or it’s not in your path
解決:C:\Users\yuta\Anaconda3\Lib\site-packages\pytesseract中pytesseract.py改路徑保存:下載tesseract.exe地址:https://github.com/tesseract-ocr/tesseract/wiki 選擇系統對應版本下載安裝,默認安裝在C:\Program Files

import cv2 as cv import numpy as np from PIL import Image import pytesseract as tess """ 預處理-去除干擾線和點 不同的結構元素中選擇 Image和numpy array相互轉換 識別和輸出 """ def recognition_demo(image):gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)cv.imshow("binary", binary)kernel = cv.getStructuringElement(cv.MORPH_RECT, (4, 4))bin1 = cv.morphologyEx(binary,cv.MORPH_OPEN, kernel=kernel)cv.imshow("bin1", bin1)textImage = Image.fromarray(bin1)text = tess.image_to_string(textImage)print("The result:", text)def main():src = cv.imread("E:\images\yzm.jpg")cv.imshow("demo",src)recognition_demo(src)cv.waitKey(0)cv.destroyAllWindows()if __name__ == '__main__':main()

16.圖像拼接/保存器

# -*- coding: utf8 -*- import cv2 img_head = cv2.imread('C:/Users/yuta/Desktop/6/20190924153611.jpg') #讀取頭像和國旗圖案 img_flag = cv2.imread('C:/Users/yuta/Desktop/6/timg (2).jpg') w_head, h_head = img_head.shape[:2] #獲取頭像和國旗圖案寬度 w_flag, h_flag = img_flag.shape[:2] print(w_head) print(h_head) print(w_flag) print(h_flag) scale = w_head / w_flag / 4 #計算圖案縮放比例 print(scale)img_flag = cv2.resize(img_flag, (0, 0), fx=scale, fy=scale) #縮放圖案 w_flag, h_flag = img_flag.shape[:2] #獲取縮放后新寬度for c in range(0, 3): #按3個通道合并圖片img_head[w_head - w_flag:, h_head - h_flag:, c] = img_flag[:, :, c] cv2.imwrite('new_head.jpg', img_head) import threading from queue import Queue import os import numpy as np from PIL import Image import time import logging# 獲取異常消息的字符串 import sys import traceback def get_exception_string():exc_type, exc_value, exc_traceback = sys.exc_info()exception_list = traceback.format_exception(exc_type, exc_value, exc_traceback)exception_string = ''.join(exception_list)return exception_stringclass ImageSaver(threading.Thread):""" 多線程的圖像文件保存器類"""def __new__(cls):""" 重寫new方法,實現單實例的效果"""if not hasattr(cls, '_instance'):father_class = super(ImageSaver, cls)cls._instance = father_class.__new__(cls)self = cls._instancesuper(ImageSaver, self).__init__()self.queue = Queue()self.start()return cls._instancedef save_image(self, argument_1, imageFilePath):"""argument_1可以是Image庫的圖像對象,或者numpy庫的ndarray(rgb通道順序)imageFilePath必須是字符串"""if isinstance(argument_1, np.ndarray):image = Image.fromarray(argument_1)else:image = argument_1put_tuple = (image, imageFilePath)self.queue.put(put_tuple)def run(self):""" 多線程的主要循環運行內容"""while True:try:if not self.queue.empty():image, imageFilePath = self.queue.get()dirPath, imageFileName = os.path.split(imageFilePath)if not os.path.isdir(dirPath):os.makedirs(dirPath)image.save(imageFilePath)except Exception as e:exception_string = get_exception_string()logging.error(exception_string)logging.error('保存到此路徑時出錯: %s' %imageFilePath)time.sleep(0.0001)


總結

以上是生活随笔為你收集整理的【Python5】图像操作,数字验证码识别,图像拼接/保存器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。