您现在的位置: 首页 > 网站导航收录 > 百科知识百科知识
regionprops_regionprops
车牌,图像,字符regionprops_regionprops
发布时间:2020-12-06加入收藏来源:互联网点击:
在上述代码中,根据给出的车牌特征剔除了那些不大可能是牌照的区域。 但是,依然还有一些区域(例如车头灯等)的外观与车牌完全一样,也有可能被标记为车牌。 为了消除这些区域,我们需要进行垂直投影:即累加每一列的全部像素。 由于车牌区域存在着字符图像,因此我们预期在车牌区域会得到很高的列像素累加值。。
字符分割在这个阶段,我们将提取车牌上的所有字符图像。 我们继续使用连通分量分析(CGA)。
import numpy as npfrom skimage.transform import resizefrom skimage import measurefrom skimage.measure import regionpropsimport matplotlib.patches as patchesimport matplotlib.pyplot as pltimport cca2# on the image I'm using, the headlamps were categorized as a license plate# because their shapes were similar# for now I'll just use the plate_like_objects[2] since I know that's the# license plate. We'll fix this later# The invert was done so as to convert the black pixel to white pixel and vice versalicense_plate = np.invert(cca2.plate_like_objects[2])labelled_plate = measure.label(license_plate)fig, ax1 = plt.subplots(1)ax1.imshow(license_plate, cmap="gray")# the next two lines is based on the assumptions that the width of# a license plate should be between 5% and 15% of the license plate,# and height should be between 35% and 60%# this will eliminate somecharacter_dimensions = (0.35*license_plate.shape[0], 0.60*license_plate.shape[0], 0.05*license_plate.shape[1], 0.15*license_plate.shape[1])min_height, max_height, min_width, max_width = character_dimensionscharacters = []counter=0column_list = []for regions in regionprops(labelled_plate): y0, x0, y1, x1 = regions.bbox region_height = y1 - y0 region_width = x1 - x0 if region_height min_height and region_height max_height and region_width min_width and region_width max_width: roi = license_plate[y0:y1, x0:x1] # draw a red bordered rectangle over the character. rect_border = patches.Rectangle((x0, y0), x1 - x0, y1 - y0, edgecolor="red", linewidth=2, fill=False) ax1.add_patch(rect_border) # resize the characters to 20X20 and then append each character into the characters list resized_char = resize(roi, (20, 20)) characters.append(resized_char) # this is just to keep track of the arrangement of the characters column_list.append(x0)plt.show()列表 plate_like_objects中存有车辆图像中所有的候选车牌区域。 在我使用的示例图像中,有三个区域被选中为车牌的候选区域。 在这个教程中,为了节省时间,我手工指定了第二个区域(真正包含车牌的区域)。 在下面分享的最终代码中会包含一个牌照区域的验证功能,可以自动剔除那些实际上不包含车牌的区域。
接下来我们在牌照上做一个连通分量分析,将每个字符的大小调整为20px,20px。 这是因为字符的大小与下一个阶段的识别有关。
为了跟踪牌照中字符的顺序,引入了column_list变量来记录每个字符区域的x轴起始坐标。 这样就可以通过排序来确定多个字符间的先后顺序了。
字符识别这是车牌识别的最后一个阶段,我们首先介绍下机器学习。 机器学习可以简单地定义为人工智能(AI)的一个发展分支,它对数据进行处理以期从数据中发现可用于预测的模式。 机器学习可以分为监督学习、无监督学习和强化学习。 监督学习使用标注过的数据集(称为训练数据集)进行预测。 我们将采用监督学习,因为我们已经知道A、B等字母的样子。 监督学习又可以分为两类: 分类和回归。 字符识别则属于分类。
我们现在需要做的:
获取训练数据集
选择监督学习分类器
训练模型
测试模型的准确率
使用模型进行预测。
让我们开始训练模型吧。 我有两个不同的数据集 ,一个是10px,20px,另一个是20px,20px。 我们将使用20px,20px的数据集,因为之前已经按这个大小调整过每个字符。 除O和I(由于它们分别与0和1相似,因此尼日利亚牌照中不使用这些字母)以外的每个字母都有10个不同的图像。
你可以尝试不同的分类器 ,每种分类器都有其优点和缺点。 在这个任务中,我们将使用支持向量分类器(SVC)。 之所以选择SVC,是因为它在这个任务中的的能表现最好。 但是,这并不是说SVC是最好的分类器。
我们需要首先安装scikit-learn软件包:
pip install scikit-learn这部分的代码如下:
import osimport numpy as npfrom sklearn.svm import SVCfrom sklearn.model_selection import cross_val_scorefrom sklearn.externals import joblibfrom skimage.io import imreadfrom skimage.filters import threshold_otsuletters = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' ]def read_training_data(training_directory): image_data = [] target_data = [] for each_letter in letters: for each in range(10): image_path = os.path.join(training_directory, each_letter, each_letter + '_' + str(each) + '.jpg') # read each image of each character img_details = imread(image_path, as_grey=True) # converts each character image to binary image binary_image = img_details threshold_otsu(img_details) # the 2D array of each image is flattened because the machine learning # classifier requires that each sample is a 1D array # therefore the 20*20 image becomes 1*400 # in machine learning terms that's 400 features with each pixel # representing a feature flat_bin_image = binary_image.reshape(-1) image_data.append(flat_bin_image) target_data.append(each_letter) return (np.array(image_data), np.array(target_data))def cross_validation(model, num_of_fold, train_data, train_label): # this uses the concept of cross validation to measure the accuracy # of a model, the num_of_fold determines the type of validation # e.g if num_of_fold is 4, then we are performing a 4-fold cross validation # it will divide the dataset into 4 and use 1/4 of it for testing # and the remaining 3/4 for the training accuracy_result = cross_val_score(model, train_data, train_label, cv=num_of_fold) print("Cross Validation Result for ", str(num_of_fold), " -fold") print(accuracy_result * 100)current_dir = os.path.dirname(os.path.realpath(__file__))training_dataset_dir = os.path.join(current_dir, 'train')image_data, target_data = read_training_data(training_dataset_dir)# the kernel can be 'linear', 'poly' or 'rbf'# the probability was set to True so as to show# how sure the model is of it's predictionsvc_model = SVC(kernel='linear', probability=True)cross_validation(svc_model, 4, image_data, target_data)# let's train the model with all the input datasvc_model.fit(image_data, target_data)# we will use the joblib module to persist the model# into files. This means that the next time we need to# predict, we don't need to train the model againsave_directory = os.path.join(current_dir, 'models/svc/')if not os.path.exists(save_directory): os.makedirs(save_directory)joblib.dump(svc_model, save_directory+'/svc.pkl')在上面的代码中,使用训练数据集中的每个字符来训练svc模型。 我们通过4折交叉验证来确定模型的精确度,然后将模型保存到模型文件中,以便后续进行预测。
现在我们有了一个训练好的模型,可以试着来预测一下我们之前分割出的字符图像:
import osimport segmentationfrom sklearn.externals import joblib# load the modelcurrent_dir = os.path.dirname(os.path.realpath(__file__))model_dir = os.path.join(current_dir, 'models/svc/svc.pkl')model = joblib.load(model_dir)classification_result = []for each_character in segmentation.characters: # converts it to a 1D array each_character = each_character.reshape(1, -1); result = model.predict(each_character) classification_result.append(result)print(classification_result)plate_string = ''for eachPredict in classification_result: plate_string += eachPredict[0]print(plate_string)# it's possible the characters are wrongly arranged# since that's a possibility, the column_list will be# used to sort the letters in the right ordercolumn_list_copy = segmentation.column_list[:]segmentation.column_list.sort()rightplate_string = ''for each in segmentation.column_list: rightplate_string += plate_string[column_list_copy.index(each)]print(rightplate_string)注意上一篇:(组词檐)-组词鸯
下一篇:返回列表
相关链接 |
||
网友回复(共有 0 条回复) |