【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中刪除原來程序,寫入下段程序:
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
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 金字塔
3.5 縮放
3.6 平移
3.7 旋轉
3.8 仿射變換
3.9 透視變換
4.形態學
腐,膨。開,閉,開閉。白帽,黑帽
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()
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)
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()
8.圖像梯度
9.canny邊緣檢測
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 讀取視頻文件
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的分量范圍:
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.平面空間到極坐標空間轉換
14.人臉檢測
haar和lap數據:https://github.com/opencv/opencv/tree/master/data
win10下載子目錄見文章:https://blog.csdn.net/weixin_43435675/article/details/88201615
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
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】图像操作,数字验证码识别,图像拼接/保存器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Python4】字符分割识别,车牌识别
- 下一篇: 【Python7】csv/excel/m