zoukankan      html  css  js  c++  java
  • python自动生成黄蓝绿车牌,并自动标注yolo模型labelImg文件

    参考作者:

    作者:Charlotte77

    出处:http://www.cnblogs.com/charlotte77/

    本文以学习、研究和分享为主,如需转载,请联系本人,标明作者和出处,非商业用途!

    介绍:本文灵感来自于作者:Charlotte77,在其自动生成车牌的基础上稍作修改,可随机生成三色车牌并标注xml文件。生成保存路径和xml保存路径以及单词随机生成个数,可在代码中设置。因为我是做车牌字符的识别,所以生成时规定了省份简称,如需更换可修改代码中相应部分,亦可随机。

    修改部分:使用pypinyin模块得到省份简称的拼音,同音字已做区分,藏字得音为cang,需要注意!后续模型分类可另作修改。

    注意:注释不一定是原作者真是用意,请加以甄别!

    RandomGenerationVLP.py
    #coding=utf-8
    """
       genPlate.py:生成随机车牌
    """
    
    __author__ = "Huxiaoman"
    __copyright__ = "Copyright (c) 2017 "
    
    import PIL
    from PIL import ImageFont
    from PIL import Image
    from PIL import ImageDraw
    import cv2
    import numpy as np
    import os
    from math import *
    import pypinyin
    import sys
    import os
    import xml.dom.minidom
    
    import pypinyin
    
    
    def genXML(plate, labels, xmlPath):  # 生成的字符列表和 标签位置
        # pinyin = pypinyin.slug(imageName[0])
        # if imageName[0] == '贵':
        #     pinyin = 'gui'
        # elif imageName[0] == '桂':
        #     pinyin = 'guilin'
        # elif imageName[0] == '甘':
        #     pinyin = 'gan'
        # elif imageName[0] == '赣':
        #     pinyin = 'jiangxi'
        # elif imageName[0] == '豫':
        #     pinyin = 'yu'
        # elif imageName[0] == '渝':
        #     pinyin = 'chongqing'
        # elif imageName[0] == '晋':
        #     pinyin = 'jin'
        # elif imageName[0] == '津':
        #     pinyin = 'tianjin'
    
        new_txtname = ''.join(plate)  #
    
        # 创建空的Dom文档对象
        doc = xml.dom.minidom.Document()
        # 创建根结点,根节点名为 annotation
        annotation = doc.createElement('annotation')  # 根节点
        # 将根节点添加到Dom文档对象中
        doc.appendChild(annotation)
    
        # folder节点
        folder = doc.createElement('folder')  # 创建一个名叫folder的节点
        # 内容写入
        folder_text = doc.createTextNode('JPEGImages')  # folder节点里面要写的内容
        folder.appendChild(folder_text)  # 添加到folder节点下,如果是内容,节点内容createTextNode类型,就作为内容写入;如果是createElement类型,就作为子节点添加进去
        annotation.appendChild(folder)  # 之后将添加好内容的folder节点,作为子节点添加到annotation节点中
    
        # filename节点
        filename = doc.createElement('filename')
        filename_text = doc.createTextNode(str(new_txtname) + '.jpg')  # 这个地方是随机生成的图片文件名
        filename.appendChild(filename_text)
        #
        annotation.appendChild(filename)
    
        # path节点
        path = doc.createElement('path')
        path_text = doc.createTextNode('E:\darknet-master\build\darknet\myVLPCharData\JPEGImages\%s.jpg' % new_txtname)
        path.appendChild(path_text)
        #
        annotation.appendChild(path)
    
        # sourch节点
        source = doc.createElement('source')
        #
        database = doc.createElement('database')
        database_text = doc.createTextNode('Unknown')
        database.appendChild(database_text)
        #
        source.appendChild(database)
        #
        annotation.appendChild(source)
    
        # size节点
        size = doc.createElement('size')
    
        width = doc.createElement('width')
        width_text = doc.createTextNode('272')
        width.appendChild(width_text)
        size.appendChild(width)
    
        height = doc.createElement('height')
        height_text = doc.createTextNode('72')
        height.appendChild(height_text)
        size.appendChild(height)
    
        depth = doc.createElement('depth')
        depth_text = doc.createTextNode('3')
        depth.appendChild(depth_text)
        size.appendChild(depth)
        #
        annotation.appendChild(size)
    
        # segmented节点
        segmented = doc.createElement('segmented')
        segmented_text = doc.createTextNode('0')
        segmented.appendChild(segmented_text)
        #
        annotation.appendChild(segmented)
    
        # object节点
        for [y1, y2, x1, x2], pChar in zip(labels, plate):
            object = doc.createElement('object')
    
            name = doc.createElement('name')
            name_text = doc.createTextNode(pChar)  # 这个地方是标签的name,也就是分类名称
            name.appendChild(name_text)
            object.appendChild(name)
    
            pose = doc.createElement('pose')
            pose_text = doc.createTextNode("Unspecified")
            pose.appendChild(pose_text)
            object.appendChild(pose)
    
            truncated = doc.createElement('truncated')
            truncated_text = doc.createTextNode("0")
            truncated.appendChild(truncated_text)
            object.appendChild(truncated)
    
            difficult = doc.createElement('difficult')
            difficult_text = doc.createTextNode("0")
            difficult.appendChild(difficult_text)
            object.appendChild(difficult)
    
            bndbox = doc.createElement('bndbox')
            #
            xmin = doc.createElement('xmin')
            xmin_text = doc.createTextNode(str(x1))
            xmin.appendChild(xmin_text)
            bndbox.appendChild(xmin)
            #
            ymin = doc.createElement('ymin')
            ymin_text = doc.createTextNode(str(y1))
            ymin.appendChild(ymin_text)
            bndbox.appendChild(ymin)
            #
            xmax = doc.createElement('xmax')
            xmax_text = doc.createTextNode(str(x2))
            xmax.appendChild(xmax_text)
            bndbox.appendChild(xmax)
            #
            ymax = doc.createElement('ymax')
            ymax_text = doc.createTextNode(str(y2))
            ymax.appendChild(ymax_text)
            bndbox.appendChild(ymax)
            #
            object.appendChild(bndbox)
            #
            annotation.appendChild(object)
    
        # 写入xml文本文件中
        if not os.path.exists(xmlPath):
            os.mkdir(xmlPath)
        fp = open(xmlPath + '/%s.xml' % new_txtname, 'w+')
        doc.writexml(fp, indent='
    ', addindent='	', newl='', encoding='utf-8')
        fp.close()
    
    
    index = {"": 0, "": 1, "": 2, "": 3, "": 4, "": 5, "": 6, "": 7, "": 8, "": 9, "": 10, "": 11, "": 12,
             "": 13, "": 14, "": 15, "": 16, "": 17, "": 18, "": 19, "": 20, "": 21, "": 22, "": 23, "": 24,
             "": 25, "": 26, "": 27, "": 28, "": 29, "": 30, "0": 31, "1": 32, "2": 33, "3": 34, "4": 35, "5": 36,
             "6": 37, "7": 38, "8": 39, "9": 40, "A": 41, "B": 42, "C": 43, "D": 44, "E": 45, "F": 46, "G": 47, "H": 48,
             "J": 49, "K": 50, "L": 51, "M": 52, "N": 53, "P": 54, "Q": 55, "R": 56, "S": 57, "T": 58, "U": 59, "V": 60,
             "W": 61, "X": 62, "Y": 63, "Z": 64}
    
    chars = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
                 "", "", "", "", "", "", "", "", "", "", "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 AddSmudginess(img, Smu):
        rows = r(Smu.shape[0] - 50)
        cols = r(Smu.shape[1] - 50)
        adder = Smu[rows:rows + 50, cols:cols + 50]
        adder = cv2.resize(adder, (50, 50))
        #adder = cv2.bitwise_not(adder)
        img = cv2.resize(img,(50,50))
        img = cv2.bitwise_not(img)
        img = cv2.bitwise_and(adder, img)
        img = cv2.bitwise_not(img)
        return img
    
    def rot(img,angel,shape,max_angel):  # com, [-30, 30), (70, 226, 3), 30
        """
            添加放射畸变
            img 输入图像
            factor 畸变的参数
            size 为图片的目标尺寸
        """
        size_o = [shape[1], shape[0]]  # [226, 70]
        size = (shape[1] + int(shape[0] * cos((float(max_angel)/180) * 3.14)), shape[0])  # (226+60=286, 70)  # 宽度也就是shape[1]的长度加上高度乘以高度的倾斜宽30/180,等于最后放射的宽度
        interval = abs(int(sin((float(angel) / 180) * 3.14) * shape[0]))  # [0, 34]  # 0到34之间整数
        pts1 = np.float32([[0, 0], [0, size_o[1]], [size_o[0], 0], [size_o[0], size_o[1]]])  # [[0, 0], [0, 70], [226, 0], [226, 70]]
        if angel > 0:
            pts2 = np.float32([[interval, 0], [0, size[1]], [size[0], 0], [size[0]-interval, size_o[1]]])  # [[0到34, 0], [0, 70], [226, 0], [226-0到34, 70]]
        else:
            pts2 = np.float32([[0, 0], [interval, size[1]], [size[0]-interval, 0], [size[0], size_o[1]]])  # [[0, 0], [0到34, 70], [226-0到34, 0], [226, 70]]
        M = cv2.getPerspectiveTransform(pts1, pts2)
        dst = cv2.warpPerspective(img, M, size)
        return dst
    
    def rotRandrom(img, factor, size):  # com, 10, (286, 70)  # com.shape = (70, 286, 3)
        """
        添加透视畸变
        """
        shape = size
        pts1 = np.float32([[0, 0], [0, shape[0]], [shape[1], 0], [shape[1], shape[0]]])
        pts2 = np.float32([[r(factor), r(factor)],
                           [r(factor), shape[0] - r(factor)],
                           [shape[1] - r(factor), r(factor)],
                           [shape[1] - r(factor), shape[0] - r(factor)]])
        M = cv2.getPerspectiveTransform(pts1, pts2)
        dst = cv2.warpPerspective(img, M, size)
        return dst
    
    def tfactor(img):
        """
        添加饱和度光照的噪声
        """
        hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
        hsv[:, :, 0] = hsv[:, :, 0]*(0.8 + np.random.random()*0.2)
        hsv[:, :, 1] = hsv[:, :, 1]*(0.3 + np.random.random()*0.7)
        hsv[:, :, 2] = hsv[:, :, 2]*(0.2 + np.random.random()*0.8)
    
        img = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
        return img
    
    def random_envirment(img, data_set):
        """
        添加自然环境的噪声
        """
        index=r(len(data_set))
        env = cv2.imread(data_set[index])
        env = cv2.resize(env,(img.shape[1],img.shape[0]))
        bak = (img==0)
        bak = bak.astype(np.uint8)*255
        inv = cv2.bitwise_and(bak,env)
        img = cv2.bitwise_or(inv,img)
        return img
    
    def GenCh(f, val):
        """
        生成中文字符
        """
        img = Image.new("RGB", (45, 70), (255, 255, 255))
        draw = ImageDraw.Draw(img)
        draw.text((0, 3), val, (0, 0, 0), font=f)
        img = img.resize((23, 70))  # 文字图片转换成了23列,70行
        A = np.array(img)
        return A
    
    def GenCh1(f,val):
        """
        生成英文字符
        """
        img=Image.new("RGB", (23, 70), (255, 255, 255))
        draw = ImageDraw.Draw(img)
        # draw.text((0, 2), val.decode('utf-8'), (0, 0, 0), font=f)
        draw.text((0, 2), val, (0, 0, 0), font=f)
        A = np.array(img)
        return A
    
    def AddGauss(img, level):  # level [1, 5)
        """
        添加高斯模糊
        """
        # return cv2.blur(img, (level*2 + 1, level*2 + 1))
        return cv2.blur(img, (5, 5))  # 可接受的模糊程度
        # return cv2.blur(img, (level, level))
    
    def r(val):  # 返回随机数
        return int(np.random.random() * val)
    
    def AddNoiseSingleChannel(single):
        """
        添加高斯噪声
        """
        diff = 255-single.max()
        noise = np.random.normal(0, 1+r(6), single.shape)
        noise = (noise - noise.min())/(noise.max()-noise.min())
        noise = diff*noise
        noise = noise.astype(np.uint8)
        dst = single + noise
        return dst
    
    def addNoise(img, sdev = 0.5, avg=10):
        img[:, :, 0] = AddNoiseSingleChannel(img[:, :, 0])
        img[:, :, 1] = AddNoiseSingleChannel(img[:, :, 1])
        img[:, :, 2] = AddNoiseSingleChannel(img[:, :, 2])
        return img
    
    
    class GenPlate:
    
        def __init__(self, fontCh, fontEng, NoPlates, xmlPath):  # "./font/platech.ttf", './font/platechar.ttf', "./NoPlates"
            self.fontC = ImageFont.truetype(fontCh, 43, 0)
            self.fontE = ImageFont.truetype(fontEng, 60, 0)
            self.img = np.array(Image.new("RGB", (226, 70), (255, 255, 255)))
            # 蓝色车牌背景图
            self.bg = cv2.resize(cv2.imread("./images/template.bmp"), (226, 70))
            # 黄色车牌背景图
            # self.bg = cv2.resize(cv2.imread("./images/y1.bmp"),(226,70))
            # # self.smu = cv2.imread("./images/smu2.jpg")
            # 绿色车牌背景图
            # self.bg = cv2.resize(cv2.imread("./images/g1.jpg"),(226,70))
            self.noplates_path = []
            self.xmlPath = xmlPath  # xml文件保存位置
            for parent, parent_folder, filenames in os.walk(NoPlates):
                # print(parent, parent_folder, filenames)
                # ./NoPlates
                # []
                # ['A01_N84E28_1.jpg', 'A01_N84E28_2.jpg', 'A01_NMV802_1.jpg', 'A01_NMV802_2.jpg', 'A02_NBD719_1.jpg', 'A02_NBD719_2.jpg', 'A03_A05F26_1.jpg', 'A03_A137U8_1.jpg', 'A03_A137U8_2.jpg', 'A03_A137U8_3.jpg', 'A03_A19Z80_0.jpg', 'A03_A19Z80_1.jpg', 'A03_A19Z80_2.jpg', 'A03_A19Z80_3.jpg', 'A03_A19Z80_4.jpg', 'A03_A19Z80_5.jpg', 'A03_A19Z80_7.jpg', 'A03_A19Z80_8.jpg', 'A03_A1L828_0.jpg', 'A03_A1L828_1.jpg', 'A03_A1L828_2.jpg', 'A03_A1L828_4.jpg', 'A03_A1Z726_1.jpg', 'A03_A203J1_1.jpg', 'A03_A203J1_2.jpg', 'A03_A2H337_0.jpg', 'A03_A2H337_2.jpg', 'A03_A2M801_1.jpg', 'A03_A2M801_2.jpg', 'A03_A4F288_1.jpg', 'A03_A5X098_1.jpg', 'A03_A60L48_0.jpg', 'A03_A60L48_1.jpg', 'A03_A60L48_2.jpg', 'A03_A60L48_3.jpg', 'A03_A60L48_4.jpg', 'A03_A63X72_1.jpg', 'A03_A6U922_1.jpg', 'A03_A6U922_2.jpg', 'A03_A722S6_0.jpg', 'A03_A79A95_1.jpg', 'A03_A7N292_1.jpg', 'A03_A82E65_1.jpg', 'A03_A82E65_2.jpg', 'A03_A85V02_1.jpg', 'A03_A8B389_1.jpg', 'A03_A8B389_2.jpg', 'A03_A8B389_3.jpg', 'A03_A8B389_4.jpg', 'A03_A8E322_1.jpg', 'A03_A9F208_1.jpg', 'A03_A9F208_2.jpg', 'A03_AAC595_0.jpg', 'A03_AAC595_2.jpg', 'A03_AAC595_3.jpg', 'A03_AAC595_4.jpg', 'A03_AAC595_5.jpg', 'A03_AAQ839_0.jpg', 'A03_AAQ839_1.jpg', 'A03_AAQ839_2.jpg', 'A03_AAQ839_4.jpg', 'A03_AAQ839_5.jpg', 'A03_ABF318_1.jpg', 'A03_ABF318_2.jpg']
                for filename in filenames:
                    path = parent + "/" + filename
                    # path = os.path.join(parent, filename)
                    # print(path)
                    self.noplates_path.append(path)
    
    
        def draw(self,val):  # val =  # 鄂ARQ2CR
            offset = 2
            self.img[0:70, offset+8:offset+8+23] = GenCh(self.fontC, val[0])  # 第一个中文的位置 x, y, w, h 在0- 70行的 第10- 第10+23=33列
            # print(offset+8, ':', offset+8+23)
            self.img[0:70, offset+8+23+6:offset+8+23+6+23] = GenCh1(self.fontE, val[1])  # 第二个城市简称的位置在 第10+23 + 6 = 39- 第39+23= 62列
            # print(offset+8+23+6, ':', offset+8+23+6+23)
            for i in range(5):
                base = offset + 8 + 23 + 6 + 23 + 17 + i*23 + i*6  # 后五位编号的位置在第二个城市代号末尾列,也就是第10+23+6+23= 62列的后面加上17= 79列,17是城市代号到后五位编号中间的防伪标记点的占距
                self.img[0:70, base: base+23] = GenCh1(self.fontE, val[i+2])
                # print(base, ':', base+23)
            return self.img
            # 总结一下:(226, 70)   10-63行
            # 省份简称 [:, 10:33],
            # 城市代号[:, 39:62],
            # 第一位编号[:, 79:102],
            # 第二位编号[:, 108:131],
            # 第三位编号[:, 137:160],
            # 第四位编号[:, 166:189],
            # 第五位编号[:, 195:218]
    
            # 放大后
            # [11: 61, 12: 39]
            # [11:61, 46: 74]
            # [11:61, 95: 122]
            # [11:61, 129: 157]
            # [11:61, 164: 192]
            # [11:61, 199: 227]
            # [11:61, 234: 262]
    
    
        def generate(self, text):  # 鄂ARQ2CR
            # if len(text) == 9:
            if len(text) == 7:
                # fg = self.draw(text.decode(encoding="utf-8"))
                # text.encode(encoding="utf-8").decode(encoding="utf-8")
                # fg = self.draw(text.encode(encoding="utf-8").decode(encoding="utf-8"))
                fg = self.draw(text)  # 鄂ARQ2CR
    
                # 白色字体  # 使用时,注释掉黑色字体部分
                fg = cv2.bitwise_not(fg)
                com = cv2.bitwise_or(fg, self.bg)
                # com = rot(com, r(60)-30, com.shape, 30)  # 放射畸变  # 整体效果为 车牌行数不变,列数拉伸成∠60°的平行四边形状
                # print(com.shape)  # (70, 286, 3)  #
                # com = rotRandrom(com, 10, (com.shape[1], com.shape[0]))  # 透视畸变  # 整体效果为 梯形拉伸,
                com = tfactor(com)  # 饱和光照的噪声
                com = random_envirment(com, self.noplates_path)  # 自然环境噪声
                com = AddGauss(com, 1+r(4))  # 添加高斯模糊
                com = addNoise(com)
                print(com.shape)
    
                # # 黑色字体  黄车牌适用  # 使用时,注释掉白色字体部分
                # com = cv2.bitwise_and(fg,self.bg)
                #
                # com = addNoise(com)  # 先添加噪音,后进行其他操作对字体颜色的影响很小
                # # com = rot(com, r(60) - 30, com.shape, 30)
                # # com = rotRandrom(com, 10, (com.shape[1], com.shape[0]))
                # com = tfactor(com)
                # com = random_envirment(com, self.noplates_path)  # 绿色车牌背景图时,要注释掉自然环境噪声,减小对字体颜色影响
                # com = AddGauss(com, 3 + r(2))
    
                return com
    
            else:
                return None
    
        def genPlateString(self, pos, val):  # -1, -1
            '''
            生成车牌String,存为图片
            生成车牌list,存为label
            '''
            plateStr = ""
            plateList = []
            box = [0, 0, 0, 0, 0, 0, 0]
            if pos != -1:
                box[pos] = 1
            for unit, cpos in zip(box, range(len(box))):
                if unit == 1:
                    plateStr += val
                    #print plateStr
                    plateList.append(val)
                else:
                    if cpos == 0:
                        # plateStr += chars[r(31)]  # 控制省份随机范围,可指定某一省份
                        plateStr += chars[11]  # 控制省份随机范围,可指定某一省份  京 0  渝 3  30封顶
                        plateList.append(plateStr)
                    elif cpos == 1:
                        plateStr += chars[41+r(24)]
                        plateList.append(plateStr)
                    else:
                        plateStr += chars[31 + r(34)]
                        plateList.append(plateStr)
            plate = [plateList[0]]
            b = [plateList[i][-1] for i in range(len(plateList))]
            plate.extend(b[1:7])  # extend() 在一个list后面,添加另一个list的多个值
            return plateStr, plate
    
        # 将生成的车牌图片写入文件夹,对应的label写入label.txt
        def genBatch(self, batchSize, pos, charRange, outputPath, size):
            if not os.path.exists(outputPath):
                os.mkdir(outputPath)
            outfile = open('label.txt', 'w')
            for i in range(batchSize):
                plateStr, plate = G.genPlateString(-1, -1)
    
                pinyin = pypinyin.slug(plateStr[0])
                if plateStr[0] == '':
                    pinyin = 'gui'
                elif plateStr[0] == '':
                    pinyin = 'guilin'
                elif plateStr[0] == '':
                    pinyin = 'gan'
                elif plateStr[0] == '':
                    pinyin = 'jiangxi'
                elif plateStr[0] == '':
                    pinyin = 'yu'
                elif plateStr[0] == '':
                    pinyin = 'chongqing'
                elif plateStr[0] == '':
                    pinyin = 'jin'
                elif plateStr[0] == '':
                    pinyin = 'tianjin'
                elif plateStr[0] == '':
                    pinyin = 'hebei'
                elif plateStr[0] == '':
                    pinyin = 'ji'
    
                labels = [
                    [11, 61, 12, 39],
                    [11, 61, 46, 74],
                    [11, 61, 95, 122],
                    [11, 61, 129, 157],
                    [11, 61, 164, 192],
                    [11, 61, 199, 227],
                    [11, 61, 234, 262]
                ]
                #  修改后的位置
                labels = [
                    [12, 61, 11, 40],
                    [12, 61, 45, 75],
                    [12, 61, 94, 123],
                    [12, 61, 128, 158],
                    [12, 61, 163, 193],
                    [12, 61, 198, 228],
                    [12, 61, 233, 263]
                ]
    
                imageName = pinyin + plateStr[1:]  # 省份简称替换成拼音
                plate[0] = pinyin  # 标签换成转换后的拼音
    
                genXML(plate, labels, self.xmlPath)  # 生成对应的标签
    
                print(imageName)
                print(plateStr, plate)  # 鄂ARQ2CR ['鄂', 'A', 'R', 'Q', '2', 'C', 'R']
                img = G.generate(plateStr)
                # print(img.shape)
                img = cv2.resize(img, size)  # (272, 72)  # 注释掉这一步是因为要get到没放大的字符位置
                # print(img.shape)
                # cv2.imwrite(outputPath + "/" + str(i).zfill(2) + ".jpg", img)
                if not os.path.exists(outputPath):
                    os.mkdir(outputPath)
                cv2.imwrite(outputPath + "/" + imageName + ".jpg", img)
                outfile.write(str(plate)+"
    ")
            outfile.close()
    # G = GenPlate("./font/platech.ttf", './font/platechar.ttf', "./NoPlates", 'E:\darknet-master\build\darknet\myVLPCharData\Annotations')
    G = GenPlate("./font/platech.ttf", './font/platechar.ttf', "./NoPlates", './xml')  # 测试修改时使用
    #G.genBatch(100, 2, range(31, 65), "./plate_100", (272, 72))
    
    if __name__ == '__main__':
        # G.genBatch(int(sys.argv[1]), 2, range(31, 65), sys.argv[2], (272, 72))
        # # # python genPlate.py 100 ./plate_100
        # G.genBatch(int(300), 2, range(31, 65), "E:\darknet-master\build\darknet\myVLPCharData\JPEGImages", (272, 72))
        G.genBatch(int(13), 2, range(31, 65), "./plate_100", (272, 72))  # 测试修改时使用
    
        classDict = {'jing': "", 'hu': "", 'tianjin': "", 'chongqing': "", 'hebei': "", 'jin': "", 'meng': "",
                     'liao': "", 'ji': "", 'hei': "", 'su': "", 'zhe': "", 'wan': "", 'min': "", 'jiangxi': "",
                     'lu': "", 'yu': "", 'e': "", 'xiang': "", 'yue': "", 'guangxi': "", 'qiong': "", 'chuan': "",
                     'gui': "", 'yun': "", 'cang': "", 'shan': "", 'gan': "", 'qing': "", 'ning': "", 'xin': ""}

    网盘文件链接(基础代码皆来自-作者:Charlotte77):

    链接:https://pan.baidu.com/s/1qPnEvZh8fzmqmOuuZfe8Ag
    提取码:m1sw 

  • 相关阅读:
    判断浏览器是pc端和移动
    高德谷歌地图切换成英文地图
    小程序修改默认的单选框复选框样式
    推荐系统| ① Movies概述
    推荐系统| ② 离线推荐&基于隐语义模型的协同过滤推荐
    数据结构与算法| 复杂度分析
    Flink| 运行架构
    机器学习| 高数-基础
    Flink| 概述| 配置安装
    推荐系统| 概述
  • 原文地址:https://www.cnblogs.com/buxian/p/13962699.html
Copyright © 2011-2022 走看看