一、信用卡卡號識別

一、思路分析

大體思路:首先拿到一張銀行卡,我們得有銀行卡號數字的0-9樣式的模板,然后再通過不同數字的輪廓的外接矩形來進行匹配,最終識別出銀行卡號所對應的數字。
銀行卡數字模板:
在這里插入圖片描述
銀行卡信息:
在這里插入圖片描述

拿到銀行卡的時候,因為銀行卡上面不僅僅只是銀行卡號,還會存在一些干擾項,這時候需要對這些干擾項進行過濾,這些干擾項和數字所在的外接輪廓大小是不相同的,故可以以此進行過濾篩選。當然,一下次不會將單個數字給定位到,拿到的也不是單個數字,絕大多數的銀行卡號都是四個為一組,接下來再對每一組中的四個數字進行拆分。

二、導包以及相關函數

from imutils import contours
import numpy as np
import argparse
import cv2
# 繪圖展示
def cv_show(name,img):cv2.imshow(name, img)cv2.waitKey(0)cv2.destroyAllWindows()
#因為銀行卡分為四個大輪廓,每個大輪廓中又包括四個數字,這里需要定義一個函數用于將識別出的四個大輪廓依次排序存放
def sort_contours(cnts, method="left-to-right"):reverse = Falsei = 0if method == "right-to-left" or method == "bottom-to-top":reverse = Trueif method == "top-to-bottom" or method == "bottom-to-top":i = 1boundingBoxes = [cv2.boundingRect(c) for c in cnts] #用一個最小的矩形,把找到的形狀包起來x,y,h,w(cnts, boundingBoxes) = zip(*sorted(zip(cnts, boundingBoxes),key=lambda b: b[1][i], reverse=reverse))#對模板上的輪廓進行排序,也就是將模板上的數字給貼個標簽return cnts, boundingBoxes#返回輪廓以及輪廓信息一個列表
#因為銀行卡數字這塊圖像會較小,需要重新指定一下圖像大小
def resize(image, width=None, height=None, inter=cv2.INTER_AREA):dim = None(h, w) = image.shape[:2]if width is None and height is None:return imageif width is None:r = height / float(h)dim = (int(w * r), height)else:r = width / float(w)dim = (width, int(h * r))resized = cv2.resize(image, dim, interpolation=inter)return resized

三、獲取模板上的數字信息

指定測試圖像以及模板圖像位置

# 設置參數
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True,help="path to input image")#指定輸入圖像
ap.add_argument("-t", "--template", required=True,help="path to template OCR-A image")#指定模板圖像
args = vars(ap.parse_args())

設置銀行卡類型參數

# 指定信用卡類型
FIRST_NUMBER = {"3": "American Express","4": "Visa","5": "MasterCard","6": "Discover Card"
}

首先處理模板圖像,模板圖像存放這0-9數字,讀取模板圖像,灰度圖、二值化

# 讀取一個模板圖像
img = cv2.imread(args["template"])
cv_show('img',img)
# 灰度圖
ref = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv_show('ref',ref)
# 二值圖像
ref = cv2.threshold(ref, 10, 255, cv2.THRESH_BINARY_INV)[1]
cv_show('ref',ref)

對二值化之后的模板圖像獲取輪廓

# 計算輪廓
#cv2.findContours()函數接受的參數為二值圖,即黑白的(不是灰度圖),cv2.RETR_EXTERNAL只檢測外輪廓,cv2.CHAIN_APPROX_SIMPLE只保留終點坐標
#返回的list中每個元素都是圖像中的一個輪廓
ref_, refCnts, hierarchy = cv2.findContours(ref.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

用紅色線進行繪制模板輪廓,定義一個空字典digits,用于存儲后續得到模板圖像輪廓信息

cv2.drawContours(img,refCnts,-1,(0,0,255),3) #用紅色線畫輪廓
cv_show('img',img)
print (np.array(refCnts).shape)#出現10個輪廓,0-9數字所對應的圖像信息
refCnts = sort_contours(refCnts, method="left-to-right")[0] #排序,從左到右,從上到下  得到模板排序完之后的輪廓
digits = {}#指定一個空字典

對模板圖像中0-9個輪廓依次去遍歷,得到信息存儲到digits字典中

# 遍歷每一個輪廓
for (i, c) in enumerate(refCnts):#在模板輪廓中不斷的去遍歷,i為輪廓的索引,c為輪廓# 計算外接矩形并且resize成合適大小(x, y, w, h) = cv2.boundingRect(c)#得到第i個輪廓的外接矩形信息roi = ref[y:y + h, x:x + w]#用外接矩形對模板圖像相同位置摳出來roi = cv2.resize(roi, (57, 88))#摳出來的模板圖像的大小可能會較小,把圖像給resize成一個差不多大小的圖像# 每一個數字對應每一個模板digits[i] = roi#把從模板中摳出來的數字存入到字典中,模板為value,索引為key
#循環結束之后,digits字典中就存放有了0-9數字的模板圖像信息

三、對測試圖像進行形態學操作,消除其他的干擾因素

根據不同情景選取合適的卷積核

# 初始化卷積核 這里主要是根據具體情況具體分析  卷積核的定義需要看具體情況而定
rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3))
sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))

對測試圖像進行預處理操作

#讀取輸入圖像,預處理
image = cv2.imread(args["image"])#讀取測試圖片
cv_show('image',image)#顯示一下測試圖像
image = resize(image, width=300)#重新resize一下圖像大小
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)#因為傳入的測試圖像是彩色圖,需要轉換為灰度圖
cv_show('gray',gray)#顯示一下灰度圖

將得到的灰度圖圖像通過禮帽操作,使得數字特征信息更加明顯

#禮帽操作,突出更明亮的區域
tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel) 
cv_show('tophat',tophat) 
gradX = cv2.Sobel(tophat, ddepth=cv2.CV_32F, dx=1, dy=0, ksize=-1)#ksize=-1相當于用3*3的
gradX = np.absolute(gradX)
(minVal, maxVal) = (np.min(gradX), np.max(gradX))
gradX = (255 * ((gradX - minVal) / (maxVal - minVal)))
gradX = gradX.astype("uint8")print (np.array(gradX).shape)
cv_show('gradX',gradX)

將數字部分進行融合到一塊,分成四個大輪廓

#通過閉操作(先膨脹,再腐蝕)將數字連在一起
gradX = cv2.morphologyEx(gradX, cv2.MORPH_CLOSE, rectKernel) 
cv_show('gradX',gradX)
#THRESH_OTSU會自動尋找合適的閾值,適合雙峰,需把閾值參數設置為0
thresh = cv2.threshold(gradX, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1] 
cv_show('thresh',thresh)#因為實際效果并不好,沒有完全融合到一塊,故再來一個閉操作
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, sqKernel) #再來一個閉操作
cv_show('thresh',thresh)

繪制測試圖像中的輪廓信息

# 計算輪廓
thresh_, threshCnts, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,	cv2.CHAIN_APPROX_SIMPLE)cnts = threshCnts
cur_img = image.copy()
cv2.drawContours(cur_img,cnts,-1,(0,0,255),3) #將處理之后的圖像輪廓繪制到原始圖像中去
cv_show('img',cur_img)
locs = []#因為對測試圖像輪廓檢測會得到很多個輪廓,其中只有數字部分輪廓是我們需要的,這里定義一個列表,用于存儲我們需要的數字輪廓

四、開始將測試圖像與模板圖像數字輪廓依次進行比較

因為測試圖像中的輪廓會有好多,我們只需要數字輪廓部分,故圖像輪廓的寬高比進行篩選

# 遍歷輪廓
for (i, c) in enumerate(cnts):# 計算矩形(x, y, w, h) = cv2.boundingRect(c)#繪制外接矩形ar = w / float(h)#算出寬高比比例,根據不同的比例篩選我們需要的數字輪廓# 選擇合適的區域,根據實際任務來,這里的基本都是四個數字一組if ar > 2.5 and ar < 4.0:#銀行卡上一般都是四個字為一組為一個輪廓,這個輪廓的寬高比是有個取值范圍的,通過這個范圍進行篩選我們需要的數字輪廓if (w > 40 and w < 55) and (h > 10 and h < 20):#符合的留下來locs.append((x, y, w, h))#將符合我們所設定的輪廓進行存儲,這些都是四個數字為一組,一共有四組輪廓信息

將篩選之后得出的輪廓進行排序存放

# 將符合的輪廓從左到右排序
locs = sorted(locs, key=lambda x:x[0])#對獲取的大輪廓從左到右排序
output = []

遍歷每個輪廓中的數字信息與模板中的數字信息比較評分

# 遍歷每一個輪廓中的數字
for (i, (gX, gY, gW, gH)) in enumerate(locs):# initialize the list of group digitsgroupOutput = []# 根據坐標提取每一個組group = gray[gY - 5:gY + gH + 5, gX - 5:gX + gW + 5]#為了使得效果處理較好,將拿到的大輪廓數據往上往下往左往右都擴大點cv_show('group',group)#顯示第i個大輪廓# 預處理group = cv2.threshold(group, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]#對第i個大輪廓二值化,為了找大輪廓中的四個數字輪廓cv_show('group',group)# 計算每一組的輪廓group_,digitCnts,hierarchy = cv2.findContours(group.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)#對第i個大輪廓依次進行輪廓檢測digitCnts = contours.sort_contours(digitCnts,method="left-to-right")[0]#對檢測出來的小輪廓從左到右排序# 計算每一組中的每一個數值for c in digitCnts:#每個大輪廓都有四個數字,對每一個大輪廓中的每一個小數字分別進行計算,此時c有4個值,因為測試圖像中有每個大輪廓有四個數字# 找到當前數值的輪廓,resize成合適的的大小(x, y, w, h) = cv2.boundingRect(c)#對大輪廓找取外接輪廓roi = group[y:y + h, x:x + w]#找到每個數字的輪廓信息roi = cv2.resize(roi, (57, 88))#這個resize的參數要與上列的模板設定的大小一致,到時候需要做模板匹配大小應該一致cv_show('roi',roi)#依次展示第i個大輪廓中的四個數字# 計算匹配得分scores = []#得到數字輪廓信息,要對模板進行比較,存儲得分信息# 在模板中計算每一個得分for (digit, digitROI) in digits.items():#將這個數字模板依次與標準模板中的十個數進行匹配# 模板匹配result = cv2.matchTemplate(roi, digitROI, cv2.TM_CCOEFF)(_, score, _, _) = cv2.minMaxLoc(result)scores.append(score)#依次將得分信息存入# 得到最合適的數字groupOutput.append(str(np.argmax(scores)))#選出得分最高的那個數即可# 畫出來cv2.rectangle(image, (gX - 5, gY - 5), (gX + gW + 5, gY + gH + 5), (0, 0, 255), 1)cv2.putText(image, "".join(groupOutput), (gX, gY - 15), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2)# 得到結果output.extend(groupOutput)#得到第c組大輪廓的四個數

五、輸出展示

# 打印結果
print("Credit Card Type: {}".format(FIRST_NUMBER[output[0]]))
print("Credit Card #: {}".format("".join(output)))
cv2.imshow("Image", image)
cv2.waitKey(0)

六、Pycharm參數設定方法

在這里插入圖片描述
找到Edit Configurations
在這里插入圖片描述
--image images/credit_card_04.png --template ocr_a_reference.png
其中:images/credit_card_04.png為測試圖片的位置、ocr_a_reference.png為銀行卡數字模板圖片的位置

七、項目完整代碼

# 導入工具包
from imutils import contours
import numpy as np
import argparse
import cv2
#import myutils# 設置參數
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True,help="path to input image")#指定輸入圖像
ap.add_argument("-t", "--template", required=True,help="path to template OCR-A image")#指定模板圖像
args = vars(ap.parse_args())# 指定信用卡類型
FIRST_NUMBER = {"3": "American Express","4": "Visa","5": "MasterCard","6": "Discover Card"
}
# 繪圖展示
def cv_show(name,img):cv2.imshow(name, img)cv2.waitKey(0)cv2.destroyAllWindows()def sort_contours(cnts, method="left-to-right"):reverse = Falsei = 0if method == "right-to-left" or method == "bottom-to-top":reverse = Trueif method == "top-to-bottom" or method == "bottom-to-top":i = 1boundingBoxes = [cv2.boundingRect(c) for c in cnts] #用一個最小的矩形,把找到的形狀包起來x,y,h,w(cnts, boundingBoxes) = zip(*sorted(zip(cnts, boundingBoxes),key=lambda b: b[1][i], reverse=reverse))#對模板上的輪廓進行排序,也就是將模板上的數字給貼個標簽return cnts, boundingBoxes#返回輪廓以及輪廓信息一個列表def resize(image, width=None, height=None, inter=cv2.INTER_AREA):dim = None(h, w) = image.shape[:2]if width is None and height is None:return imageif width is None:r = height / float(h)dim = (int(w * r), height)else:r = width / float(w)dim = (width, int(h * r))resized = cv2.resize(image, dim, interpolation=inter)return resized# 讀取一個模板圖像
img = cv2.imread(args["template"])
cv_show('img',img)
# 灰度圖
ref = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv_show('ref',ref)
# 二值圖像
ref = cv2.threshold(ref, 10, 255, cv2.THRESH_BINARY_INV)[1]
cv_show('ref',ref)# 計算輪廓
#cv2.findContours()函數接受的參數為二值圖,即黑白的(不是灰度圖),cv2.RETR_EXTERNAL只檢測外輪廓,cv2.CHAIN_APPROX_SIMPLE只保留終點坐標
#返回的list中每個元素都是圖像中的一個輪廓
ref_, refCnts, hierarchy = cv2.findContours(ref.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)cv2.drawContours(img,refCnts,-1,(0,0,255),3) #用紅色線畫輪廓
cv_show('img',img)
print (np.array(refCnts).shape)#出現十個輪廓
refCnts = sort_contours(refCnts, method="left-to-right")[0] #排序,從左到右,從上到下  得到模板排序完之后的輪廓
digits = {}#指定一個空字典# 遍歷每一個輪廓
for (i, c) in enumerate(refCnts):#在模板輪廓中不斷的去遍歷,i為輪廓的索引,c為輪廓# 計算外接矩形并且resize成合適大小(x, y, w, h) = cv2.boundingRect(c)#得到第i個輪廓的外接矩形信息roi = ref[y:y + h, x:x + w]#用外接矩形對模板圖像相同位置摳出來roi = cv2.resize(roi, (57, 88))#摳出來的模板圖像的大小可能會較小,把圖像給resize成一個差不多大小的圖像# 每一個數字對應每一個模板digits[i] = roi#把從模板中摳出來的數字存入到字典中,模板為value,索引為key
#循環結束之后,digits字典中就存放有了0-9數字的模板圖像信息# 初始化卷積核
rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3))
sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))#讀取輸入圖像,預處理
image = cv2.imread(args["image"])#讀取測試圖片
cv_show('image',image)#顯示一下測試圖像
image = resize(image, width=300)#重新resize一下圖像大小
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)#因為傳入的測試圖像是彩色圖,需要轉換為灰度圖
cv_show('gray',gray)#顯示一下灰度圖#禮帽操作,突出更明亮的區域
tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel) 
cv_show('tophat',tophat) 
# 
gradX = cv2.Sobel(tophat, ddepth=cv2.CV_32F, dx=1, dy=0, ksize=-1)#ksize=-1相當于用3*3的gradX = np.absolute(gradX)
(minVal, maxVal) = (np.min(gradX), np.max(gradX))
gradX = (255 * ((gradX - minVal) / (maxVal - minVal)))
gradX = gradX.astype("uint8")print (np.array(gradX).shape)
cv_show('gradX',gradX)#通過閉操作(先膨脹,再腐蝕)將數字連在一起
gradX = cv2.morphologyEx(gradX, cv2.MORPH_CLOSE, rectKernel) 
cv_show('gradX',gradX)
#THRESH_OTSU會自動尋找合適的閾值,適合雙峰,需把閾值參數設置為0
thresh = cv2.threshold(gradX, 0, 255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1] 
cv_show('thresh',thresh)#再來一個閉操作
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, sqKernel) #再來一個閉操作
cv_show('thresh',thresh)# 計算輪廓
thresh_, threshCnts, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,	cv2.CHAIN_APPROX_SIMPLE)cnts = threshCnts
cur_img = image.copy()
cv2.drawContours(cur_img,cnts,-1,(0,0,255),3) #將處理之后的圖像輪廓繪制到原始圖像中去
cv_show('img',cur_img)
locs = []#因為對測試圖像輪廓檢測會得到很多個輪廓,其中只有數字部分輪廓是我們需要的,這里定義一個列表,用于存儲我們需要的數字輪廓# 遍歷輪廓
for (i, c) in enumerate(cnts):# 計算矩形(x, y, w, h) = cv2.boundingRect(c)#繪制外接矩形ar = w / float(h)#算出寬高比比例,根據不同的比例篩選我們需要的數字輪廓# 選擇合適的區域,根據實際任務來,這里的基本都是四個數字一組if ar > 2.5 and ar < 4.0:#銀行卡上一般都是四個字為一組為一個輪廓,這個輪廓的寬高比是有個取值范圍的,通過這個范圍進行篩選我們需要的數字輪廓if (w > 40 and w < 55) and (h > 10 and h < 20):#符合的留下來locs.append((x, y, w, h))#將符合我們所設定的輪廓進行存儲,這些都是四個數字為一組,一共有四組輪廓信息# 將符合的輪廓從左到右排序
locs = sorted(locs, key=lambda x:x[0])#對獲取的大輪廓從左到右排序
output = []# 遍歷每一個輪廓中的數字
for (i, (gX, gY, gW, gH)) in enumerate(locs):# initialize the list of group digitsgroupOutput = []# 根據坐標提取每一個組group = gray[gY - 5:gY + gH + 5, gX - 5:gX + gW + 5]#為了使得效果處理較好,將拿到的大輪廓數據往上往下往左往右都擴大點cv_show('group',group)#顯示第i個大輪廓# 預處理group = cv2.threshold(group, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]#對第i個大輪廓二值化,為了找大輪廓中的四個數字輪廓cv_show('group',group)# 計算每一組的輪廓group_,digitCnts,hierarchy = cv2.findContours(group.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)#對第i個大輪廓依次進行輪廓檢測digitCnts = contours.sort_contours(digitCnts,method="left-to-right")[0]#對檢測出來的小輪廓從左到右排序# 計算每一組中的每一個數值for c in digitCnts:#每個大輪廓都有四個數字,對每一個大輪廓中的每一個小數字分別進行計算,此時c有4個值,因為測試圖像中有每個大輪廓有四個數字# 找到當前數值的輪廓,resize成合適的的大小(x, y, w, h) = cv2.boundingRect(c)#對大輪廓找取外接輪廓roi = group[y:y + h, x:x + w]#找到每個數字的輪廓信息roi = cv2.resize(roi, (57, 88))#這個resize的參數要與上列的模板設定的大小一致,到時候需要做模板匹配大小應該一致cv_show('roi',roi)#依次展示第i個大輪廓中的四個數字# 計算匹配得分scores = []#得到數字輪廓信息,要對模板進行比較,存儲得分信息# 在模板中計算每一個得分for (digit, digitROI) in digits.items():#將這個數字模板依次與標準模板中的十個數進行匹配# 模板匹配result = cv2.matchTemplate(roi, digitROI, cv2.TM_CCOEFF)(_, score, _, _) = cv2.minMaxLoc(result)scores.append(score)#依次將得分信息存入# 得到最合適的數字groupOutput.append(str(np.argmax(scores)))#選出得分最高的那個數即可# 畫出來cv2.rectangle(image, (gX - 5, gY - 5), (gX + gW + 5, gY + gH + 5), (0, 0, 255), 1)cv2.putText(image, "".join(groupOutput), (gX, gY - 15), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2)# 得到結果output.extend(groupOutput)#得到第c組大輪廓的四個數# 打印結果
print("Credit Card Type: {}".format(FIRST_NUMBER[output[0]]))
print("Credit Card #: {}".format("".join(output)))
cv2.imshow("Image", image)
cv2.waitKey(0)

八、測試圖片和模板圖片

模板圖像:
模板圖片
測試圖像:
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

九、運行效果展示

在這里插入圖片描述
在這里插入圖片描述在這里插入圖片描述

在這里插入圖片描述
在這里插入圖片描述

在這里插入圖片描述在這里插入圖片描述在這里插入圖片描述在這里插入圖片描述在這里插入圖片描述在這里插入圖片描述

在這里插入圖片描述
在這里插入圖片描述在這里插入圖片描述
在這里插入圖片描述在這里插入圖片描述在這里插入圖片描述在這里插入圖片描述
在這里插入圖片描述在這里插入圖片描述
在這里插入圖片描述在這里插入圖片描述在這里插入圖片描述在這里插入圖片描述
在這里插入圖片描述在這里插入圖片描述
在這里插入圖片描述在這里插入圖片描述在這里插入圖片描述在這里插入圖片描述
在這里插入圖片描述在這里插入圖片描述
在這里插入圖片描述在這里插入圖片描述在這里插入圖片描述在這里插入圖片描述
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/377884.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/377884.shtml
英文地址,請注明出處:http://en.pswp.cn/news/377884.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

bootstrap網格系統_如何使用Bootstrap網格系統?

bootstrap網格系統In the last article, we learned how to create a simple page of Bootstrap? Now, we will learn what is "Grid System" in Bootstrap and how we can use or implement it in our bootstrap page? As you know bootstrap is a mobile-friendl…

有關WriteableBitmap和BitmapImage之間的相互轉換

對于WP7中圖形處理有關WriteableBitmap和BitmapImage之間的相互轉換&#xff0c;給大家幾個簡單實用的方法。一、WriteableBitmap轉為BitmapImage對象var bi new BitmapImage(); bi.SetSource(wb.ToImage().ToStream()); //其中wb是WriteableBitmap對象。 二、BitmapImage轉為…

回溯法初步

本文為參考公眾號所做的筆記。 代碼隨想錄原文 回溯法本質是窮舉&#xff0c;窮舉所有可能&#xff0c;然后選出我們想要的答案&#xff0c;所以它并不是一個高效的算法。但是由于有些問題本身能用暴力搜出來就不錯了&#xff0c;所以回溯法也有很多的應用。 回溯法解決的問題…

QEMU中smp,socket,cores,threads幾個參數的理解

在用QEMU創建KVM guest的時候&#xff0c;為了指定guest cpu資源&#xff0c;用到了-smp, -sockets, -cores, -threads幾個參數&#xff0c; #/usr/bin/qemu-system-x86_64 -name pqsfc085 -enable-kvm -m 2048 -smp 2,sockets2,cores1,threads1 \ -boot ordernc,onced \ -hda …

二、文檔掃描OCR

一、思路分析 首先&#xff0c;拿到一張文檔&#xff0c;我們需要對文檔進行預處理操作&#xff0c;再進行輪廓檢測&#xff0c;因為就算拿到文檔輪廓&#xff0c;但是這些輪廓也有可能是歪歪扭扭的&#xff0c;這時候需要通過一系列的透視變換操作&#xff0c;將文檔擺正。通…

ruby hash方法_Ruby中帶有示例的Hash.select方法

ruby hash方法哈希選擇方法 (Hash.select Method) In this article, we will study about Hash.select Method. The working of this method can be predicted with the help of its name but it is not as simple as it seems. Well, we will understand this method with the…

leetcode 77. 組合 思考分析

目錄1、題目2、回溯法思路3、參考其他思路&#xff0c;更深入了解這個問題4、剪枝優化可能需要回顧到的知識文章&#xff1a;1、常用算法總結(窮舉法、貪心算法、遞歸與分治算法、回溯算法、數值概率算法)2、回溯法初步刪除vector容器中的對象元素的三種方法:pop_back, erase與…

ASP 調用dll(VB)及封裝dll實例

ASP調用dll及封裝dll實例&#xff0c;封裝為dll可以提供運行效率&#xff0c;加密代碼。 打開VB6&#xff0c;新建ActiveX DLL 2、在工程引用中加入Microsoft Active Server Pages Object Library選擇 3、填加代碼如下Code Start 聲明部分 Private MyScriptingContext As Scrip…

三、全景拼接

一、項目所涉及到的一些知識點 Ⅰ&#xff0c;BF(Brute-Force)暴力匹配&#xff1a;把兩張圖像的特征點全部給算出來&#xff0c;然后使用歸一化的歐氏距離比較這兩張圖像上特征點之間的大小關系&#xff0c;越小越相似。 SIFT算法 import cv2 import numpy as np import ma…

找回自建SVN密碼

自建了一個SVN Repo自己用。重裝系統之后密碼忘了。 經過了漫長的Google過程&#xff0c;才知道Repo中的密碼居然是明文保存的。 在yourRepoDir/conf/svnserve.conf下的password-db處設置&#xff0c;通常是yourRepoDir/conf/passwd文件。 打開passwd文件&#xff0c;就是明文保…

ruby hash方法_Ruby中帶有示例的Hash.invert方法

ruby hash方法Hash.invert方法 (Hash.invert Method) In this article, we will study about Hash.invert Method. The working of this method can be predicted with the help of its name but it is not as simple as it seems. Well, we will understand this method with …

leetcode 216. 組合總和 III 思考分析

可能需要回顧的文章; leetcode 77. 組合 思考分析 1、題目 找出所有相加之和為 n 的 k 個數的組合。組合中只允許含有 1 - 9 的正整數&#xff0c;并且每種組合中不存在重復的數字。 說明&#xff1a; 所有數字都是正整數。 解集不能包含重復的組合。 2、遞歸 這一題和之前…

【Unity】Update()和FixedUpdate()

Update()每幀調用&#xff0c;FixedUpdate&#xff08;&#xff09;以指定頻率被調用。可以在 Edit -> project settings -> Time -> Fixed Timestep 中設定該頻率。轉載于:https://www.cnblogs.com/xiayong123/p/3717002.html

約束執行區域(CER)

受約束的執行區域 (CER) 是創作可靠托管代碼的機制的一部分。CER 定義一個區域&#xff0c;在該區域中公共語言運行庫 (CLR) 會受到約束&#xff0c;不能引發可使區域中的代碼無法完全執行的帶外異常。在該區域中&#xff0c;用戶代碼受到約束&#xff0c;不能執行會導致引發帶…

python 抓取網頁鏈接_從Python中的網頁抓取鏈接

python 抓取網頁鏈接Prerequisite: 先決條件&#xff1a; Urllib3: It is a powerful, sanity-friendly HTTP client for Python with having many features like thread safety, client-side SSL/TSL verification, connection pooling, file uploading with multipart encod…

四、模擬英語四六級答題卡識別閱卷評分

一、思路分析 首先拿到答題卡照片的時候&#xff0c;需要對照片進行一系列預處理操作&#xff0c;通過透視變換將圖像擺正方便后續的操作。每一道題五個選項&#xff0c;有五道題&#xff0c;通過字典存放準確答案。沒有依次對答題卡進行輪廓檢測&#xff0c;這里采用的是正方…

leetcode 17. 電話號碼的字母組合 思考分析

題目 給定一個僅包含數字 2-9 的字符串&#xff0c;返回所有它能表示的字母組合。 給出數字到字母的映射如下&#xff08;與電話按鍵相同&#xff09;。注意 1 不對應任何字母。 思考與遞歸程序 解空間樹的寬度是輸入數字對應的字符的個數&#xff0c;深度是輸入的數字的個數…

Blockquotes,引用,html里面,經常用到的一個!

blockquote元素的使用已經非常多樣化&#xff0c;但語義上它只適用于一件事–標記了一段你的網頁被引用從另一來源。這意味著&#xff0c;如果你想讓那些花俏的引文&#xff0c;<blockquote>是不是你應該使用元素。讓我們看一看如何你應該使用此元素&#xff1a; <art…

仔細分析了下這7行,貌似時間復雜度,空間復雜度都不大,為嘛就是執行效率這么低?...

for(Girl girl Girls.first(); !myGirlFriend.like(me); girl Girls.next()){if(!girl.hasBoyFriend(now) && i.like(girl)) { GirlFriend myGirlFriend (GirlFriend)girl; }} 轉載于:https://www.cnblogs.com/naran/archive/2011/12/28/2305467.html…

BHMS的完整形式是什么?

BHMS&#xff1a;順勢療法醫學和外科學士 (BHMS: Bachelor of Homeopathic Medicine and Surgery) BHMS is an abbreviation of Bachelor of Homeopathic Medicine and Surgery. It is a medical degree program for under graduation in Homeopathy; an alternative move towa…