一.模块说明

本平台采用Django框架搭建Web服务平台,使用WSGI,对外开放API提供图像识别服务。
平台成功部署后,可以通过
打码平台说明给出平台支持的每种验证码的说明。

代码结构

  • API

    • lib:
    • 1.公共函数类库
    • 2.实现每个具体解码类型的实现:
      每个包实现一个Action类,并定于本模块对应的验证码的类型编号,如:2001
      实现 decodeCaptcha接口
    class Action(object):
    CAPTCHA_TYPE = '2001'
    def decodeCaptcha(self, request,lb,model):
    
    • 3.对外接口说明展示,增加对应字典项(views.py)
     {'captcha_type': '2001','paramDesc': 'captcha_type = 2001,image=图像字节流字符串','ResultDesc': '验证码内容,示例:4241,如果未能识别成功,返回空字符串。','examples_patch': r'http://kdzwy.kss.ksyun.com/file/installation/CaptchaPlatform/images/2001.png','alt': '80*30','description': '深圳社保:https://sipub.sz.gov.cn/hsoms/authcode?','model_filename':os.path.join(TRAINING_DATA_PATH, 'models', 'model2001','model.hdf5'), # r'static\models\model2001\model.hdf5','label_filename':os.path.join(TRAINING_DATA_PATH, 'models', 'model2001','labels.dat') #r'static\models\model2001\labels.dat'}
    
  • CaptchaPlatform
    定义服务的相关配置(settings.py)和对外开放接口(urls.py)

  • ml 机器学习相关模块:

    • 1.数据采集模块da(Data Acquisition)
    • 2.数据处理模块dp(Data Processing)
    • 3.模型训练模块tran (Model Traning)

二.开发一个新的图形解码类型的主要步骤

1.采集对应的模板图片

  • 在ml.da.example.py 中添加一个对该类图像的定义的字典:

    dct2010 = {'url': r'https://etax.shenzhen.chinatax.gov.cn/login-web/api/googleCaptcha?1593310982512','savepath': os.path.join(TRAINING_DATA_PATH, 'sourceimages', '2010') #r'E:\ML\TrainData\sourceimages\2010'#r"..\..\static\sourceimages\2010"}
    
    • url: 表示可以直接通过url可以访问到的该类图像的地址
    • savepath: 表示通过采集模块采集到的样本图像的存放地址
  • 定义

    • 在 generate_images中定义对应图像类型采用的采集方式。(如调用dataAcquisition中的不同函数)
    • 在generate_images也可以定义此每次运行需要采集的图像数量(修改range的范围)
    • 如果是新增加的类型,我们可以使用联众的方式,自动将采集的图像先打标。
      (如调用generate_labeled_images时将decoder设置为lianzhong,如果是训练完成后来验证自己模型的准确率时,可以将该参数设置成localhost,
      既使用本平台自己的接口来采集并打标对应的图形)
       def generate_images(da,thread_index,type):try:for i in range(1,21):print("开始处理第{}个线程的第{}组数据!".format(str(thread_index),str(i)))start = datetime.now()print("开始时间:{}".format(start))if (type==1002):da.generate_labeled_images_jiangsu(dct1002['url'], dct1002['savepath'],'lianzhong')elif(type==2007):da.generate_labeled_images(dct2007['url'], dct2007['savepath'], 2007,4,4,'localhost')elif (type == 2008):#da.generate_labeled_images(dct2008['url'], dct2008['savepath'], 1014, 6, 6, 'lianzhong')da.generate_labeled_images(dct2008['url'], dct2008['savepath'], 2008, 6, 6, 'localhost')elif (type == 2009):#da.generate_labeled_images2(dct2009['url'], dct2009['savepath'], 1014, 6, 6, 'lianzhong')da.generate_labeled_images(dct2009['url'], dct2009['savepath'], 2009, 6, 6, 'localhost')time.sleep(1)elif (type == 2010):#da.generate_labeled_images2(dct2010['url'], dct2010['savepath'], 1014, 4, 4, 'lianzhong')da.generate_labeled_images(dct2010['url'], dct2010['savepath'], 2010, 4, 4, 'localhost')elif (type == 2005):da.generate_labeled_images(dct2005['url'], dct2005['savepath'], 2005, 4, 4, 'mock')elif (type == 3002):da.generate_labeled_images(dct3002['url'], dct3002['savepath'], 3002, 4, 4, 'www')end = datetime.now()spendTime = (end - start).total_seconds()print("结束时间:{}".format(end))print("共耗时:{}秒 ================================================".format(spendTime))finally:if (type == 1002):da.quiteDriver()return
    

2.编写对应的数据处理模块

  • 数据处理模块主要是实现图形验证码的拆分逻辑:整体目标是将构成验证码的字符拆分成单个的字符

    • 添加对应的Package,命名规程为:splitimage+类型编号,如:splitimage2001
    • 添加splitimage.py文件
    • 在splitimage.py中定义类:splitimage
    • 在类splitimage中实现splitImagebySp方法
      # 数据处理模块class splitimage(object):# 根据特征拆分图片:# 裁剪图片,经观察,该验证码大小统一为80*30像素,中间为4个数值字符;# 合理的裁剪为平均大小裁剪,每个图片被裁剪成20*30的大小# 设置图像裁剪区域# 左边从第二个像素开始,顶部从第三个像素开始def splitImagebySp(self, img):# img = Image.open(imgpath)  # 打开当前路径图像box = [0, 1, 2, 3]imgSplited = []for j in range(0, len(box)):# crop函数的4个参数分别为:左,上,右,下,请参考:https://blog.csdn.net/HANNING563128766/article/details/79969339box[j] = (20 * j, 2, 20 * (j + 1), 30)  # 裁剪后高度有2个像素的差(移去了顶部2个像素),因此第四个参数定义为18,实际裁剪后的图片高度为16imgLetter = img.crop(box[j])  # 图像裁剪imgSplited.append(imgLetter)return imgSplited
    • 调整ml.dp.example.py中运行extracte_letter_images方法对应的参数为当前图像对应的编号
    • 运行ml.dp.example.py,将采集并已经打标的原始图片拆分成单个的字符的集合
    • 打开保存拆分后文件的路径extracted_letter_images,检查已经拆分的字符是否与清晰准确
      如果发现存在明显错误的图片,如在A文件夹中发现某个被拆分的字符对应的图像明显不是A字符,则可以
      将对应的文件删除,以便后续提高模型训练的准确性。

3.数据&特征预处理与训练模型

  • 实现步骤

    • (1).准备用于训练的数据集;

      • 为了能更加方便地收集训练的数据集,平台设计了一个数据采集的框架,具体实现请参考前面模块介绍中的:数据采集模块da(Data Acquisition)
    • (2).将构成验证码的字符拆分成单个的字符;

      • 某种特定的验证码图像总是由特定个数字母组成。如果我们能用某种方式把图像分割开来,请参考前面提到的 数据处理模块,这样每一个字母都是一个独立的图像,那么我们只需要训练神经网络一次识别一个字母:
        这个过程我们可以想象成教一个从未受到过任何识字教育小朋友学习认字(母)。一般最好是一个字或一个字母地教,而不是孩子们连字母都还没有认识,就先教他单词。
      • 拆分后单个字符:
        我们可以看到,由于我们拆分字符的算法也许并非完美,从而导致某些字符有一些干扰信息或者不完整,但是这没有关系!
        为什么呢?说到这里,我们需要先了解一下 卷积神经网络 的实现原理了。
        在此之前,请仔细阅读并理解上述百度百科知识!

        抛开一系列繁琐的公式,我们只需要这样理解:
        就像我们拿着不同字体,不同人书写的同一个字去教识字的小朋友认字。这些字当中,有的写得歪点,有的斜点,都没有关系,只要
        抓取这个字符的最主要特征。
        卷积神经网络(CNN)能够利用图像数据的移位不变性、局部连通性和组合性。因此,CNNs可以提取局部有意义的特征,并与整个数据集共享,用于各种图像分析。
    • (3).训练模型;

      • 调整ml.train.example.py中的参数,其中captcha_type为当前要训练的模型的类别,训练完成后将产生2个
        model.hdf5和labels.dat
      import cv2
      import pickle
      import os.path
      import numpy as np
      from imutils import paths
      from sklearn.preprocessing import LabelBinarizer
      from sklearn.model_selection import train_test_split
      from keras.models import Sequential
      from keras.layers.convolutional import Conv2D, MaxPooling2D
      from keras.layers.core import Flatten, Dense
      from CaptchaPlatform.settings import *
      # 数据训练模块
      # Build by James zhang 2019.08
      # 训练神经网络,并生成训练结果
      class dataTrain(object):def train_model(self, captcha_type, output_cnt, letter_width, letter_height,batch_size=100, epochs=15):                letter_images_folder =os.path.join(TRAINING_DATA_PATH,'extracted_letter_images', captcha_type)                model_filename = os.path.join(TRAINING_DATA_PATH,'models', 'model{}\model.hdf5'.format(captcha_type))                labels_filename = os.path.join(TRAINING_DATA_PATH,'models', 'model{}\labels.dat'.format(captcha_type))# 初始化标签data = []labels = []        # 遍历图片for image_file in paths.list_images(letter_images_folder):# 将加载的图片转换为灰度图image = cv2.imread(image_file)                    image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)                      # 进行维度转换,以便适应后续的计算                    # expand_dims(a, axis)就是在axis的那一个轴上把数据加上去,这个数据在axis这个轴的0位置。image = np.expand_dims(image, axis=2)# 按文件夹名称打标label = image_file.split(os.path.sep)[-2]# 图片文件数据与标签同下标data.append(image)labels.append(label)# 二维化序列data = np.array(data, dtype="float") / 255.0labels = np.array(labels)# 设置测试数据百分比(X_train, X_test, Y_train, Y_test) = train_test_split(data, labels, test_size=0.25, random_state=0)# 将标签矩阵二值化lb = LabelBinarizer().fit(Y_train)Y_train = lb.transform(Y_train)Y_test = lb.transform(Y_test)# 保存标签数据with open(labels_filename, "wb") as f:pickle.dump(lb, f)# 创建神经网络model = Sequential()# 第一个具有最大池的卷积层# 第一层卷积神经网络,注意,在这里letter_height, letter_width应该设置成跟目标图像一致的大小                model.add(Conv2D(20, (5, 5), padding="same", input_shape=(letter_height, letter_width, 1), activation="relu"))model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))# 第二个具有最大池的卷积层model.add(Conv2D(50, (5, 5), padding="same", activation="relu"))model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))# 具有500节点的隐藏层model.add(Flatten())model.add(Dense(500, activation="relu"))# 具有X个节点的输出层(每个可能的字母/数值一个) model.add(Dense(output_cnt, activation="softmax"))                # 要求Keras在幕后构建TensorFlow模型# 损失函数categorical_crossentropy:交叉熵损失函数#交叉熵是用来评估当前训练得到的概率分布与真实分布的差异情况。#它刻画的是实际输出(概率)与期望输出(概率)的距离,也就是交叉熵的值越小,两个概率分布就越接近。model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])        # 训练神经网络model.fit(X_train, Y_train, validation_data=(X_test, Y_test), batch_size=batch_size, epochs=epochs, verbose=1)                # 保存模型model.save(model_filename)
      
      • 重点代码解析:
      • 下述代码是以类型为2009的验证码为例的运行过程
      # 将加载的图片转换为灰度图
      image = cv2.imread(image_file)
      image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
      
      • 用CV2.imread读取图片数据,图片每个像素包含RGB3个颜色通道
    • 二值化后可以用一个二维数组保存图片的全部重要信息

    • 二值化后图片特征并未消失

     # 扩展维度(既将一个二维数组,转换为三维),以便适应后续的计算  image = np.expand_dims(image, axis=2)
    
    • 扩展维度(既将一个二维数组,转换为三维),以便适应后续的计算

    • 拆分后的所有图片数据被添加到一个List中
        #按文件夹名称打标 label = image_file.split(os.path.sep)[-2]#图片文件数据与标签同下标data.append(image)labels.append(label)
    

    • 将图像数据转换为浮点数存储于一个4维的数据集中
       data = np.array(data, dtype="float") / 255.0labels = np.array(labels)
    

    • 设置训练数据与测试数据百分比
    (X_train, X_test, Y_train, Y_test) = train_test_split(data, labels, test_size=0.25, random_state=0)
    
    • 通过train_test_split函数将数分为训练数据和测试数据两组
    • 这里将测试数据定义为0.25既25%,则训练数据占比75%
    • 因此训练数据为:77574*75%=58180
    • 每组数据又分为X,Y
    • X轴保存图像数据

      • Y轴保存对应的标签序列

      • 通过上述操作,我们就将所有的图片数据和对应的标签数据以这种巧妙的方式全部存储在了内存中,并有了一一的对应关系

      • 接下来,为了最大程度的减少计算量,我们再将标签矩阵二值化

         lb = LabelBinarizer().fit(Y_train)Y_train = lb.transform(Y_train)Y_test = lb.transform(Y_test)
      
      • 执行完lb = LabelBinarizer().fit(Y_train),我们得到了一个所有可能出现的标签的集合

      • 既我们得到了一个标签序列去重后的结果,这与我们可能的标签集合数量正好一致

      • 执行完Y_train = lb.transform(Y_train),我们得到了一个标签二值化后的矩阵数据

      • 如上图所示,我们可以很容易地看出,每个标签数据对应坐标,
        比如:Y轴上的第一个标签数据,对应的是28个标签数据的第6个(从0开始),既lb中的下标为5的数据:字符7

      • 我们再看看之前的Y轴数据为对应的标签序列,第一个数据正好对应的是字符7

      • 标签二值化的好处和目的是什么,大家可以参考一下:

      • 特征工程系列:特征预处理

      • 下面我们就开始使用具有两个卷积层和两个完全连接层的简单卷积神经网络结构来完成单个字符识别的模型训练。

      • 用Keras定义这个神经网络体系结构只需要使用几行代码:

      • 如果你想知道更多关于卷积神经网络是如何工作的,为什么他们被用作图像识别非常理想,请参考。

      • 卷积神经网络是如何工作的

4.测试模型准确率

  • 模型预加载准备:

    • 将上述数据处理模块中拆分出来的任意一个文件复制一份到 CaptchaPlatform\static\images文件夹下,并重新命名为[验证码类型]_letter.png
  • 调整ml\da\example.py参数,将调用generate_labeled_images时decoder设置为localhost, 既使用本地代码自己的接口来打标对应的图形。
    decoder:对应参数(lianzhong:使用联众平台;localhost:使用本地代码;mock:使用模拟环境;www:使用正式环境)
  • 启动本地服务

    或者运行 python.exe manage.py runserver
  • 运行测试程序: python.exe E:\autotax\CaptchaPlatform\ml\da\example.py
    • 可以通过调整generate_images函数中range的范围,来调整测试采样的数量。
    • 测试程序运行完成后可以在系统指定的输出路径:CaptchaPlatform\settings.py中定义:[TRAINING_DATA_PATH
      \sourceimages\验证码类型] 这个路径下面看到通过本地平台解码的验证码图片。观察图片的名称与实际的图形,通过统计正确解码的验证图片来
      确定当前训练的模型的准确率,并确定是否达到了使用的标准。

三.关于机器学习-深度学习-计算机视觉学习领域的基础知识和应用

1.使用TensorFlow机器学习框架破解字符型验证

  • 我们的工具集

    • 在我们进一步讨论之前,让我们说一下为了解决这个问题我们将会用到的工具:

      • Python3:
        Python是一种编程语言,它有很好的机器学习和计算机视觉库。
      • OpenCV:
        OpenCV是一种流行的计算机视觉和图像处理框架。我们将使用OpenCV来处理验证码图像。
        它有一个Python应用接口,因此我们可以直接从Python中使用它。
      • TensorFlow:
        TensorFlow是谷歌的机器学习库。我们会在Keras中写代码,但Keras并没有真正实现神经网络的逻辑本身,它其实是在后台调用谷歌的TensorFlow进行计算。
      • Keras:
        Keras是一个由Python写的深度学习的框架。它可以使我们用最少的代码,方便地定义、训练和使用深层神经网络。
  • 关于TensorFlow 的参考资料:

    • TensorFlow 官方文档中文版
    • Tensorflow 一些常用基本概念与函数

四.利用OpenCv破解汉字点选类&滑块距离类验证码

  • 关于OpenCv 的参考资料:

    • 史上最全的OpenCV入门教程
    • python中PIL.Image和OpenCV图像格式相互转换
    • cv2.matchTemplate模板匹配和cv2.minMaxLoc()函数
  • 实例说明:

    • 深圳地区电子税局文字点选验证码:
  • 验证方式:用户通过依次点击文字完成验证。

  • 我们的目标便是识别图像中的具体文字,并确定其坐标位置。(图片中底部的白色文字部分是通过程序添加上去的,目的是为了将需要标注位置的目标文字直接在图片中说明出来。)
    原始的模式为原图+文字说明,也就是说,我们在得到一张图片时,也同时可以得到需要点选的文字到底是哪几个字。

  • 解决思路:

    • 前期通过付费接口采集大量带标注的数据
    • 将带标注的样本通过算法拆分,将其分解成单个汉字

    • 拆分后每个从图片中裁剪出来的汉字保存在对应的文件夹中
    • 使用cv2.matchTemplate将对应文件夹中的汉字图片逐一匹配原始图像,如果发现相似度大于了特定值(85%),
      则认为找到了匹配的汉字,最相似部分坐标max_loc则对应着这个汉字的左上角坐标位置
    • 深圳地区样本数量在25万左右,3次以内重试的识别成功率达到了99%
  • 实例说明:

    • 江苏地区电子税局滑块拖动验证码:
  • 验证方式:用户通过向右拖动滑块填充拼图完成验证。

  • 我们的目标是计算出滑块填充区域相对于背景图最左边距离

  • 解决思路:

    • 实际场景中我们可以获取到2张图片,一张为被拖动的滑块的图片,另一张为背景图片
    • 从轮廓上,我们可以看出第一张图片与背景图中的缺口位置的外部轮廓是大体一致的
    • 写一段测试代码,利用cv2.matchTemplate尝试找出缺口处的位置
    • cv2.matchTemplate 有6中匹配方式,可以每种方式都尝试一下,然后返回匹配度最高的值:
      • CV_TM_SQDIFF 平方差匹配法:该方法采用平方差来进行匹配;最好的匹配值为0;匹配越差,匹配值越大。
      • CV_TM_CCORR 相关匹配法:该方法采用乘法操作;数值越大表明匹配程度越好。
      • CV_TM_CCOEFF 相关系数匹配法:1表示完美的匹配;-1表示最差的匹配。
      • CV_TM_SQDIFF_NORMED 归一化平方差匹配法
      • CV_TM_CCORR_NORMED 归一化相关匹配法
      • CV_TM_CCOEFF_NORMED 归一化相关系数匹配法
  • 采集一批样本,并按特定规则命名,使得我们能容易将两块图片关联起来:

  • 编写测试代码,将所有采集的样本返回的位置用矩形框框起来,方便我们判断是否找到了正确的位置。

def GetPos(imgsr, imgtm):# 与模版比对,找到匹配图像的相似度矩阵try:result = []res1 = cv2.matchTemplate(imgsr, imgtm, cv2.TM_SQDIFF)min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res1)result.append((min_val, max_val, min_loc, max_loc))res2 = cv2.matchTemplate(imgsr, imgtm, cv2.TM_SQDIFF_NORMED)min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res2)result.append((min_val, max_val, min_loc, max_loc))res3 = cv2.matchTemplate(imgsr, imgtm, cv2.TM_CCORR)min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res3)result.append((min_val, max_val, min_loc, max_loc))res4 = cv2.matchTemplate(imgsr, imgtm, cv2.TM_CCORR_NORMED)min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res4)result.append((min_val, max_val, min_loc, max_loc))res5 = cv2.matchTemplate(imgsr, imgtm, cv2.TM_CCOEFF)min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res5)result.append((min_val, max_val, min_loc, max_loc))res6 = cv2.matchTemplate(imgsr, imgtm, cv2.TM_CCOEFF_NORMED)min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res6)result.append((min_val, max_val, min_loc, max_loc))except:print("未找到匹配的位置!")# 从6组中找到相似度最高,既max_val最大的那一组for res in result:print('Max_Val:{}'.format(res[1]))if res[1] > max_val:min_val, max_val, min_loc, max_loc = res[0], res[1], res[2], res[3]img = cv2.rectangle(imgsr, max_loc, (max_loc[0] + imgtmw1, max_loc[1] + imgtmh1), (0, 0, 255), 1)# 从相似度矩阵中抽取最大,最小值,其中最大值即为相似度最高部分的左上角坐标# img = cv2.rectangle(imgsr, max_loc, (max_loc[0] + imgtmw1, max_loc[1] + imgtmh1), (0, 0, 255), 1)cv2.imwrite(r"c:\temp.jpg", img)cv2.imshow('Image', img)print(max_loc[0])print(max_loc[0] + imgtmw1, max_loc[1] + imgtmh1)cv2.waitKey(0)cv2.destroyAllWindows()
  • 将所有采集的样本返回的位置用框框起来

  • 判断成功的样本

  • 判断失误的样本

  • 可以看到并非所有的样本都返回了正确的位置,因此,需要继续优化。

  • 考虑到这些图片缺口的图像轮廓都相似,实际与颜色无关,如果将图片转换为灰度图可以忽略颜色带来的影响。

  • 检查运行结果,发现依然有判断失误的样本

  • 初步分析,我们认为是背景干扰了匹配,如何去掉背景的干扰?很简单,使用cv2.threshold(imgsr, 120, 255, cv2.THRESH_BINARY)
    设置一个阈值, 我们可以跟粗暴地将整个背景变为2中颜色,非黑即白。要么与要寻找的轮廓相同,要么完全不同。(注意,原来转为为灰度图有255个值)

  • 经过阈值处理后,我们可以看到,所有的样本都找到了正确的位置。

  • 将测试成功后代码将其添加在对应的Action.decodeCaptcha中即可

打造一个基于机器学习的图像解码平台相关推荐

  1. python dag调度系统开发_基于机器学习的DAG调度平台

    什么是DAG? 有向无环图 树形结构:除根节点,每个节点有且仅有一个上级节点,下级节点不限.根节点没有上级节点. 图结构:每个节点上级.下级节点数不限. DAG调度平台的定义及场景 任务调度是在各行各 ...

  2. php如何开发调色器,PHP imagecreate - 新建一个基于调色板的图像

    imagecolorallocate - 新建一个基于调色板的图像. 语法 imagecreate ( int $x_size , int $y_size ) : resource imagecolo ...

  3. 一个基于区块链的AI平台即将ICO:这可以说是今年最潮的项目了

    李林 编译自 Wired 量子位 出品 | 公众号 QbitAI 这个项目,看起来就是个年度科技热词全家桶: 一家创业公司即将进行ICO,来为基于区块链的人工智能平台SingularityNET筹集资 ...

  4. 手握曹操出行,吉利为什么还要打造一个新的网约车平台?

    网约车江湖,又要掀起一场"腥风血雨"了. 据部分媒体从吉利汽车(00175.HK)母公司吉利控股集团人士处获悉,吉利集团将推出网约车聚合平台"幸福千万家",主要 ...

  5. 机器学习 | 一个基于机器学习的简单小实践:波斯顿房价预测分析

    本文采用Kaggle上面的Boston HousePrice数据集展示了如何建立机器学习模型的通常过程,包括以下几个阶段: 数据获取 数据清洗 探索性数据分析 特征工程 模型建立 模型集成 标签变量( ...

  6. 推荐一个基于 Vue 的低代码平台

    发现了一个开源的低代码平台项目,用户仅仅通过简单的拖拉拽就能生成一个页面.交互方式类似于创客贴.Processon平台. 这个项目基于 Vue.js 技术栈,先来看这个开源项目有什么功能,平台主页面分 ...

  7. linux 查找文件夹_用python打造一个基于socket的文件(夹)传输系统

    这段时间在学习python,接触到了网络编程中的socket这块,加上自己在用的Linux服务器都是原生支持python的,于是乎有了个做文件传输功能程序的想法. 毕竟python语言中,有下载功能的 ...

  8. 支持mp4的rtsp服务器,基于Windows服务器,从0开始搭建一个基于RTSP协议的直播平台...

    作案工具下载 EasyDarwin 服务端程序,用来接受推流和拉流 FFmpeg 可以用来推流视频数据到服务端,也可以从服务端拉流下来播放,也可以从一个服务端拉流下来,转推到另一个服务端去. Easy ...

  9. 【timm】一个基于pytorch的图像模型库

    参考:https://rwightman.github.io/pytorch-image-models/ 该库包含了很多种类的涉及图像模型,包括ViT. 安装 pip install timm #或者 ...

  10. 写一个基于MATLAB的图像均值滤波去噪代码

    首先,需要载入图像.在 MATLAB 中,可以使用函数 imread 来载入图像.例如: I = imread('image.jpg'); 然后,可以使用函数 imfilter 来对图像进行均值滤波. ...

最新文章

  1. Velocity 入门(一)
  2. 自动驾驶之路已走了多远?一文读懂研究现状
  3. boost源码剖析之:多重回调机制signal(下)
  4. bat php 监控网站,HTML_进程监控实现代码[vbs+bat],运行后会在%windir%\system32\目录 - phpStudy...
  5. Python类中的self到底是干啥的
  6. C语言中 \r, \n, \b
  7. h5页面保存img_如何设计H5编辑器中的模版库并实现自动生成封面图
  8. Python以字符形式打印双色图片中的文字
  9. java继承 后的方法_Java 继承
  10. leetcode python3 简单题141. Linked List Cycle
  11. ESFramework网络通信框架介绍之(5)――消息分派器IMessageDispatcher
  12. Connection reset原因分析和解决方案
  13. 奈奎斯特定理和香农定理之科普篇
  14. 训练赛第三场A题 zoj 559
  15. java调用flex_转载:在JavaScript中调用Flex方法
  16. 代数方程与差分方程模型(三):按年龄分组的人口模型
  17. Android NDK-EGL 初级
  18. 程序员做外包,真的没地位没出路吗?
  19. 计算机内存不足黑屏怎么办,win10内存不足会黑屏吗_win10电脑内存不足黑屏了怎么办...
  20. python3.7 openpyxl函数 拆分 excel 单元格

热门文章

  1. gromacs 中关于二级结构分析
  2. 通过JS导出Excel。将JS数组转换为VB数组
  3. 关于百度SDK的返回错误-PERMISSION UNFINISHED
  4. 大数据教程:数据可视化(ECharts)
  5. EMV规范(九)——持卡人验证(CVM)三
  6. js中易错难点集合(1)
  7. java图书商城项目_JavaWeb之网上图书商城-框架搭建
  8. 七夕表白java代码_身为程序猿的你,七夕表白代码你有get吗
  9. 内蒙古小学计算机老师招聘试题及答案,2016内蒙古事业单位计算机考试题库:计算机考试练习题(57)...
  10. Aruco物体定位(追踪)在UE4中的实现