安装Anacond:https://blog.csdn.net/ITLearnHall/article/details/81708148

安装Pycharm:https://blog.csdn.net/qq_15698613/article/details/86502371

一:MyQR 生成动态二维码100个

import random 
from MyQR import myqr
import os

for i in range(1,101):
    z=''.join(str(random.choice(range(10))) for _ in range(10))#生成长度为10的随机数
    name=z+".png"#设置图片名字
    myqr.run(
    version=1,  # 设置容错率
    level='L',
    brightness=1.0,
    words=z,
    save_name=name
)

二:下载图片,将图片和二维码大小进行修改

需要安装opencv参考

https://blog.csdn.net/iracer/article/details/80498732

import os
import cv2

#读取文件夹下文件
def read_directory(directory_name,save_img):
    i=0
    for fileName in os.listdir(directory_name):
        #print(fileName)
        obsPath=directory_name+"/"+fileName
        obsSave_path=save_img+"/"+fileName
        resize_img(obsPath,obsSave_path)
        i+=1
        if(i==100):
            break
def resize_img(path_img,save_img):
    im1 = cv2.imread(path_img)
    im2 = cv2.resize(im1,(716,1000),)  # 为图片重新指定尺寸
    cv2.imwrite(save_img,im2)

read_directory("D:/pythonLearnDemo/AnacondaJqueryDemo/neg/neg","D:/pythonLearnDemo/AnacondaJqueryDemo/neg/resize_neg")

三:将照片和二维码进行随机合并

import cv2
import numpy as np
import matplotlib.pyplot as plt
import random
#读取照片
directory_name="D:/pythonLearnDemo/AnacondaJqueryDemo/neg/resize_neg"
myqrPaths=os.listdir("D:/pythonLearnDemo/AnacondaJqueryDemo/neg/myqrCode")
lens=len(os.listdir(directory_name))
for fileName in os.listdir(directory_name):
    obsPathName=directory_name+"/"+fileName
    yNum=0
    xNum=0
    for i in range(1,3):
        
        dst = cv2.imread(obsPathName)#背景图
        ranNum=random.randint(0,lens)
        print("ranNum:",ranNum,"NAME:",myqrPaths[ranNum])
        srcPath="D:/pythonLearnDemo/AnacondaJqueryDemo/neg/myqrCode"+"/"+myqrPaths[ranNum]
        x_loc=0
        y_loc=0
        
        if(i==1):
            y_loc=random.randint(141,350)
            yNum=y_loc
            x_loc=random.randint(141,260)
            xNum=x_loc
        else:
            y_loc=random.randint(yNum+170,641)
            x_loc=random.randint(xNum+141,500)
        center = (x_loc,y_loc)
        #dst = cv2.imread("D:/pythonLearnDemo/AnacondaJqueryDemo/neg/opencv-seamless-cloning-example.jpg.jpg")
        print(srcPath)
        src = cv2.imread(srcPath)
        src_mask = np.zeros(src.shape, src.dtype)
        poly = np.array([[0, 2], [258, 2], [258, 260], [0, 260]], np.int32)
        cv2.fillPoly(src_mask, [poly], (255, 255, 255))
        output = cv2.seamlessClone(src, dst, src_mask, center, cv2.NORMAL_CLONE)
        mrgPath="D:/pythonLearnDemo/AnacondaJqueryDemo/neg/images"+"/"+fileName
        obsPathName=mrgPath
        cv2.imwrite(mrgPath, output);

下载安装Tensorflow object detection API :https://github.com/tensorflow/models下载到本地,解压放到需要使用的路径下

 四:Protobuf 安装与配置

  Protobuf(Google Protocol Buffers)是GG开发的的一套用于数据存储,网络通信时用于协议编解码的工具库。和XML,Json数据差不多,把数据按某种形式保存起来。相对与XML和Json的不同之处,它是一种二进制的数据格式,具有更高的传输,打包和解包效率。

  在https://github.com/google/protobuf/releases 网站中选择windows 版本,解压后将bin文件夹中的【protoc.exe】放到models中的research目录下,执行下面的代码,将object_detection/protos下的.proto文件转换成.py文件

'''

需要到protoc所在的目录下执行protoc

'''

import os

os.chdir( 'models-master/research' )#可以写

for each in os.listdir( 'object_detection/protos' ):#可以写models-master(Tensorflow object detection API 解压后文件)可对路径

    if each.endswith('proto'):

        os.system('protoc object_detection/protos/%s --python_out=.' % each)

运行jupyter notebook,找到../models-master/research/object_detection下的

object_detection_tutorial.ipynb进行运行

demo结果

  如果代码成功运行的话,运行结果如下图所示:

给图片打标签

  使用打标签工具LabelImg,下载页面链接:https://tzutalin.github.io/labelImg/

  下载后解压,打开:

  在输入法为英文输入的情况下,按键盘上的w键则可以开始绘制方框,方框会框住图片中的物体。完成绘制方框后,还需要为方框标上类别,如下图所示。

  注意:每完成一张图的打标签,一定要记得保存!!!,初次使用可以在edit选项中设置正方形和矩形框:

 每次打完标签,会生成对应的xml数据,感兴趣的可以查看一下某个xml文件,其中记录了标签及bounding box坐标:

<annotation>
    <folder>images</folder>
    <filename>1.jpg</filename>
    <path>D:\pythonLearnDemo\AnacondaJqueryDemo\neg\images\1.jpg</path>
    <source>
        <database>Unknown</database>
    </source>
    <size>
        <width>716</width>
        <height>1000</height>
        <depth>3</depth>
    </size>
    <segmented>0</segmented>
    <object>
        <name>qrCode</name>
        <pose>Unspecified</pose>
        <truncated>0</truncated>
        <difficult>0</difficult>
        <bndbox>
            <xmin>141</xmin>
            <ymin>222</ymin>
            <xmax>355</xmax>
            <ymax>436</ymax>
        </bndbox>
    </object>
    <object>
        <name>qrCode</name>
        <pose>Unspecified</pose>
        <truncated>0</truncated>
        <difficult>0</difficult>
        <bndbox>
            <xmin>369</xmin>
            <ymin>422</ymin>
            <xmax>561</xmax>
            <ymax>605</ymax>
        </bndbox>
    </object>
</annotation>

xml转csv

 xml转csv的意思是,将xml文件中的信息整合到csv文件中,其中利用的是xml模块

# -*- coding: utf-8 -*-
"""
@author: Zbb
将文件夹内所有XML文件的信息记录到CSV文件中
"""

import os
import pandas as pd
import xml.etree.ElementTree as ET
from sklearn.model_selection import train_test_split

path = 'D:/pythonLearnDemo/saveLabels'

def xml_to_csv(path):
    xml_list = []
    for xml_file in glob.glob(path + '/*.xml'):
        tree = ET.parse(xml_file)
        root = tree.getroot()
        for member in root.findall('object'):
            value = (root.find('filename').text,
                     int(root.find('size')[0].text),
                     int(root.find('size')[1].text),
                     member[0].text,
                     int(member[4][0].text),
                     int(member[4][1].text),
                     int(member[4][2].text),
                     int(member[4][3].text)
                     )
            xml_list.append(value)
    column_name = ['filename', 'width', 'height', 'class', 'xmin', 'ymin', 'xmax', 'ymax']
    xml_df = pd.DataFrame(xml_list, columns=column_name)
    return xml_df

def xmlPath_list_to_df(xmlPath_list):
    xmlContent_list = []
    for xmlPath in xmlPath_list:
        print(xmlPath)
        tree = ET.parse(xmlPath)
        root = tree.getroot()

for member in root.findall('object'):
            value = (root.find('filename').text,  # 文件名
                     int(root.find('size')[0].text),  # width
                     int(root.find('size')[1].text),  # height
                     member[0].text,  # 标签
                     int(member[4][0].text),  # xmin
                     int(member[4][1].text),  # ymin
                     int(member[4][2].text),  # xmax
                     int(member[4][3].text)  # ymax
                     )
            xmlContent_list.append(value)

column_name = ['filename', 'width', 'height', 'class', 'xmin', 'ymin', 'xmax', 'ymax']

xmlContent_df = pd.DataFrame(xmlContent_list, columns=column_name)

return xmlContent_df

def main():
    image_path = path
    xml_df = xml_to_csv(image_path)
    xml_df.to_csv('tv_vehicle_labels.csv', index=None)
    print('Successfully converted xml to csv.')

def dirPath_to_csv(dirPath):
    fileName_list = os.listdir(dirPath)
    all_xmlPath_list = [os.path.join(dirPath, fileName) for fileName in fileName_list if '.xml' in fileName]
    train_xmlPath_list, test_xmlPath_list = train_test_split(all_xmlPath_list, test_size=0.1, random_state=1)
    train_df = xmlPath_list_to_df(train_xmlPath_list)
    train_df.to_csv('train.csv')
    print('成功产生文件train.csv,训练集共有%d张图片' % len(train_xmlPath_list))

test_df = xmlPath_list_to_df(test_xmlPath_list)
    test_df.to_csv('test.csv')
    print('成功产生文件test.csv,测试集共有%d张图片' % len(test_xmlPath_list))
#main()
dirPath_to_csv(path)

csv转tfrecord

  由于下面的代码我们需要模块

1

from object_detection.utils import dataset_util

  该模块是我们在Tensorflow object detection API中下载的,要想使用该模块,我们需要添加环境变量PATHPATH。方法如下:右键计算机->属性

其中变量值包含下载的objec_detection路径及slim路径,如E:\ML\models-master\research;E:\ML\models-master\research\slim 

# -*- coding: utf-8 -*-
"""
@author: Zbb
将文件夹内所有XML文件的信息记录到CSV文件中
"""

import os
import io
import pandas as pd
import tensorflow as tf

from PIL import Image
from object_detection.utils import dataset_util
from collections import namedtuple, OrderedDict

import os
import pandas as pd
import tensorflow as tf
from object_detection.utils import dataset_util
import shutil

def csv2tfrecord(csv_path, imageDir_path, tfrecord_path):
    objectInfo_df = pd.read_csv(csv_path)
    tfrecord_writer = tf.python_io.TFRecordWriter(tfrecord_path)
    for filename, group in objectInfo_df.groupby('filename'):
        height = group.iloc[0]['height']
        width = group.iloc[0]['width']
        filename_bytes = filename.encode('utf-8')
        image_path = os.path.join(imageDir_path, filename)

with open(image_path, 'rb') as file:
            encoded_jpg = file.read()

image_format = b'jpg'
        xmin_list = list(group['xmin'] / width)
        xmax_list = list(group['xmax'] / width)
        ymin_list = list(group['ymin'] / height)
        ymax_list = list(group['ymax'] / height)

classText_list = [classText.encode('utf-8') for classText in group['class']]
        classLabel_list = [classText_to_classLabel(classText) for classText in group['class']]

tf_example = tf.train.Example(features=tf.train.Features(
            feature={
                'image/height': dataset_util.int64_feature(height),
                'image/width': dataset_util.int64_feature(width),
                'image/filename': dataset_util.bytes_feature(filename_bytes),
                'image/source_id': dataset_util.bytes_feature(filename_bytes),
                'image/encoded': dataset_util.bytes_feature(encoded_jpg),
                'image/format': dataset_util.bytes_feature(image_format),
                'image/object/bbox/xmin': dataset_util.float_list_feature(xmin_list),
                'image/object/bbox/xmax': dataset_util.float_list_feature(xmax_list),
                'image/object/bbox/ymin': dataset_util.float_list_feature(ymin_list),
                'image/object/bbox/ymax': dataset_util.float_list_feature(ymax_list),
                'image/object/class/text': dataset_util.bytes_list_feature(classText_list),
                'image/object/class/label': dataset_util.int64_list_feature(classLabel_list),

}))
        tfrecord_writer.write(tf_example.SerializeToString())

tfrecord_writer.close()
    print('成功产生tfrecord文件,保存在路径:%s' % tfrecord_path)

# 如果训练自己的模型,目标检测类别不同,需要修改此处
def classText_to_classLabel(row_label):
    if row_label == 'fish':
        return 1
    elif row_label == 'human_face':
        return 2
    else:
        return None

dir_name = 'training'
if not os.path.isdir(dir_name):
    os.mkdir(dir_name)

csv2tfrecord('D:/pythonLearnDemo/train.csv', 'D:/pythonLearnDemo/AnacondaJqueryDemo/neg/images', 'D:/pythonLearnDemo/training/train.tfrecord')
csv2tfrecord('D:/pythonLearnDemo/test.csv', 'D:/pythonLearnDemo/AnacondaJqueryDemo/neg/images', 'D:/pythonLearnDemo/training/test.tfrecord')

  运行上面的代码,目标检测文件夹中会产生一个文件夹training,如下图所示:

编写pbtxt文件

  目标检测的文件夹training中,创建文本文件my_label_map.pbtxt。复制下面一段内容到文本文件my_label_map.pbtxt中:

item {
    name : "qrCode"
    id : 1
}

8)编写配置文件

  可以在object_detection文件夹中的samples/config路径下,找到原生配置文件ssdlite_mobilenet_v2_coco.config,先复制1份到桌面文件目标检测的文件夹training中,并做如下修改:

  1. 第9行的num_classes,对于本文来说,此数设置为1
  2. 第141行的batch_size,对于本文来说,此数设置为3,读者根据自己的电脑配置,可以调高或者调低
  3. 第177行input_path设置成"D:/pythonLearnDemo/training/train.tfrecord"(我设置的为绝对路径)
  4. 第179行label_map_path设置成"D:/pythonLearnDemo/training/my_label_map.pbtxt"
  5. 第191行input_path设置成"D:/pythonLearnDemo/training/test.tfrecord"
  6. 第193行label_map_path设置成"D:/pythonLearnDemo/training/my_label_map.pbtxt"
  7. 第158、159这2行需要删除
  8. 第二处为eval_config中的num_examples,它表示在验证阶段需要执行的图片数量,本次验证数量为10(可以在create_pascal_tf_record.py中,输出对应的examples_list长度,就可以知道这个大小)。

  修改配置文件ssdlite_mobilenet_v2_coco.config并保存后,此时文件夹training中有4个文件,如下图所示:

# SSD with Mobilenet v1 configuration for MSCOCO Dataset.
# Users should configure the fine_tune_checkpoint field in the train config as
# well as the label_map_path and input_path fields in the train_input_reader and
# eval_input_reader. Search for "PATH_TO_BE_CONFIGURED" to find the fields that
# should be configured.

model {
  ssd {
    num_classes: 1
    box_coder {
      faster_rcnn_box_coder {
        y_scale: 10.0
        x_scale: 10.0
        height_scale: 5.0
        width_scale: 5.0
      }
    }
    matcher {
      argmax_matcher {
        matched_threshold: 0.5
        unmatched_threshold: 0.5
        ignore_thresholds: false
        negatives_lower_than_unmatched: true
        force_match_for_each_row: true
      }
    }
    similarity_calculator {
      iou_similarity {
      }
    }
    anchor_generator {
      ssd_anchor_generator {
        num_layers: 6
        min_scale: 0.2
        max_scale: 0.95
        aspect_ratios: 1.0
        aspect_ratios: 2.0
        aspect_ratios: 0.5
        aspect_ratios: 3.0
        aspect_ratios: 0.3333
      }
    }
    image_resizer {
      fixed_shape_resizer {
        height: 300
        width: 300
      }
    }
    box_predictor {
      convolutional_box_predictor {
        min_depth: 0
        max_depth: 0
        num_layers_before_predictor: 0
        use_dropout: false
        dropout_keep_probability: 0.8
        kernel_size: 1
        box_code_size: 4
        apply_sigmoid_to_scores: false
        conv_hyperparams {
          activation: RELU_6,
          regularizer {
            l2_regularizer {
              weight: 0.00004
            }
          }
          initializer {
            truncated_normal_initializer {
              stddev: 0.03
              mean: 0.0
            }
          }
          batch_norm {
            train: true,
            scale: true,
            center: true,
            decay: 0.9997,
            epsilon: 0.001,
          }
        }
      }
    }
    feature_extractor {
      type: 'ssd_mobilenet_v1'
      min_depth: 16
      depth_multiplier: 1.0
      conv_hyperparams {
        activation: RELU_6,
        regularizer {
          l2_regularizer {
            weight: 0.00004
          }
        }
        initializer {
          truncated_normal_initializer {
            stddev: 0.03
            mean: 0.0
          }
        }
        batch_norm {
          train: true,
          scale: true,
          center: true,
          decay: 0.9997,
          epsilon: 0.001,
        }
      }
    }
    loss {
      classification_loss {
        weighted_sigmoid {
        }
      }
      localization_loss {
        weighted_smooth_l1 {
        }
      }
      hard_example_miner {
        num_hard_examples: 3000
        iou_threshold: 0.99
        loss_type: CLASSIFICATION
        max_negatives_per_positive: 3
        min_negatives_per_image: 0
      }
      classification_weight: 1.0
      localization_weight: 1.0
    }
    normalize_loss_by_num_matches: true
    post_processing {
      batch_non_max_suppression {
        score_threshold: 1e-8
        iou_threshold: 0.6
        max_detections_per_class: 100
        max_total_detections: 100
      }
      score_converter: SIGMOID
    }
  }
}

train_config: {
  batch_size: 3
  optimizer {
    rms_prop_optimizer: {
      learning_rate: {
        exponential_decay_learning_rate {
          initial_learning_rate: 0.004
          decay_steps: 800720
          decay_factor: 0.95
        }
      }
      momentum_optimizer_value: 0.9
      decay: 0.9
      epsilon: 1.0
    }
  }
  #fine_tune_checkpoint: "PATH_TO_BE_CONFIGURED/model.ckpt"
  #from_detection_checkpoint: true
  # Note: The below line limits the training process to 200K steps, which we
  # empirically found to be sufficient enough to train the pets dataset. This
  # effectively bypasses the learning rate schedule (the learning rate will
  # never decay). Remove the below line to train indefinitely.
  num_steps: 200000
  data_augmentation_options {
    random_horizontal_flip {
    }
  }
  data_augmentation_options {
    ssd_random_crop {
    }
  }
}

train_input_reader: {
  tf_record_input_reader {
    input_path: "D:/pythonLearnDemo/training/train.tfrecord"
  }
  label_map_path: "D:/pythonLearnDemo/training/my_label_map.pbtxt"
}

eval_config: {
  num_examples: 10
  # Note: The below line limits the evaluation process to 10 evaluations.
  # Remove the below line to evaluate indefinitely.
  max_evals: 10
}

eval_input_reader: {
  tf_record_input_reader {
    input_path: "D:/pythonLearnDemo/training/test.tfrecord"
  }
  label_map_path: "D:/pythonLearnDemo/training/my_label_map.pbtxt"
  shuffle: false
  num_readers: 1
}

三、模型训练

 1)错误一:

  在桌面的目标检测文件夹中打开cmd,即在路径中输入cmd后按Enter键运行。在cmd中运行命令:

1

1.    python D:/tensorflowObject/models-master/research/object_detection/model_main.py  
--pipeline_config_path=D:/pythonLearnDemo/training/ssd_mobilenet_v1_coco.config  
--model_dir=D:/pythonLearnDemo/training/model_training
 --alsologtostderr

2.  python3 object_detection/model_main.py 
    --pipeline_config_path=D:/pythonLearnDemo/training/ssd_mobilenet_v1_coco.config  
    --model_dir=D:/pythonLearnDemo/training/model_training
    --num_train_steps=500000 #设置训练步长
    --num_eval_steps=2000
    --alsologtostderr

  运行结果如下图所示:

  可以看出缺少pycocotools库,在linux系统中安装pycocotools库只需要运行命令:pip install pycocotools但是在Windows上安装则复杂得多:

 首先下载Microsoft C++ build 14.0,链接:https://go.microsoft.com/fwlink/?LinkId=691126,初始化安装程序->自定义->选择功能只勾选Windows 10 SDK 10.0.10240->安装,过程比较漫长,一般安装有VS完整版的,不会缺失

  然后下载安装pycocotools,链接:https://github.com/philferriere/cocoapi,解压到当前文件夹,进入文件夹cocoapi-master中的文件夹PythonAPI,在此文件夹下打开cmd,输入:python setup.py build_ext install

 

 然后重新训练,模型训练稳定地进行一段时间后,会做一次模型评估,如下图所示。所以如果读者看到下图中的情况,则说明模型训练很顺利:

将训练模型导出

python D:/tensorflowObject/models-master/research/object_detection/export_inference_graph.py 
--input_type=image_tensor  
--pipeline_config_path=D:/pythonLearnDemo/training/ssd_mobilenet_v1_coco.config  
--trained_checkpoint_prefix=D:/pythonLearnDemo/training/model_training/model.ckpt-20000  #之前默认设置20000次
--output_directory=fish_inference_graph 

3)查看模型训练状况

  模型训练稳定地进行后,在桌面的目标检测文件夹中重新打开cmd。在cmd中运行命令:

D:/pythonLearnDemo/training/model_training(路径为之前保存训练模型的地方)--trained_checkpoint_prefix=D:/pythonLearnDemo/training/model_training/

tensorboard --logdir=D:/pythonLearnDemo/training/model_training --host=127.0.0.1

可查看数据

测试

测试代码下载地址
链接:https://pan.baidu.com/s/1kqFlP6vdsMgwyYRPFPmxnA
提取码:68rc 

在测试过程中,出现不了展示图片大的效果,然后修改成了保存

训练结果

后续需要进行动态视频测试!

TensorFlow Object Detection API 超详细教程和踩坑过程相关推荐

  1. MMDetectionV2 + Colab 超详细教程及踩坑实录

    文章目录 前言 一.环境配置 二.准备自己的数据集 Aug.14更新 三:修改config文件 3.1 文件结构 3.2 (本地)修改config文件 3.2.1 (本地)构造自己模型的权重文件 3. ...

  2. ubuntu下谷歌开源的TensorFlow Object Detection API的安装教程

    环境 Ubuntu16.04/anaconda+tensorflow(gpu)1.4.0+python=3.5 下载 tensorflow model 估计下载的很慢,提供一个百度云链接:https: ...

  3. Tensorflow object detection API 搭建物体识别模型

    ----------------------------------------------------先把别人博客教程跑通-------------------------------------- ...

  4. Tensorflow object detection API训练自己的目标检测模型 详细配置教程 (一)

    Tensorflow object detection API 简单介绍Tensorflow object detection API: 这个API是基于tensorflow构造的开源框架,易于构建. ...

  5. 物体识别,Win7下运行TensorFlow Object Detection API详细版教程(零基础操作)

    这段时间在做三维重建,为了达到更好的重建效果,想在三维重建的工作开始前增加物体识别这一功能,以便针对特定的物体进行相应的优化,国内也不乏有众多公司在做通用图片识别,诸如:旷世,商汤,百度,图普等,这里 ...

  6. 关于使用tensorflow object detection API训练自己的模型-补充部分(代码,数据标注工具,训练数据,测试数据)

    之前分享过关于tensorflow object detection API训练自己的模型的几篇博客,后面有人陆续碰到一些问题,问到了我解决方法.所以在这里补充点大家可能用到的东西.声明一下,本人专业 ...

  7. Tensorflow object detection API 搭建属于自己的物体识别模型(转载修改)

    Tensorflow object detection API 搭建属于自己的物体识别模型 电脑配置信息 开始搭建环境 测试自带案例 准备训练图片 配置文件与模型 开始训练模型 生成最终的训练文件 测 ...

  8. 谷歌开放的TensorFlow Object Detection API 效果如何?对业界有什么影响

    ? 谷歌开放了一个 Object Detection API: Supercharge your C 写个简单的科普帖吧. 熟悉TensorFlow的人都知道,tf在Github上的主页是:tenso ...

  9. 如何在windows系统上安装Tensorflow Object Detection API?

    前言 都说Linux是最适合程序员使用的操作系统,这话还真不假. 之前一直在云服务器上跑代码,近期接手了师兄的台式机(GTX 1050),虽然配置很渣,但想在本地玩玩看,于是乎先安装一波Tensorf ...

最新文章

  1. 老调重弹:插件式框架开发的一个简单应用
  2. 纯内存linux,7、内存知识和Linux基本原则
  3. Oracle表分区详细说明
  4. 关于Domain-Specific Languages
  5. 计算机包括桌面计算机和便携式计算机,()计算机包括桌面计算机和便携式计算机这两种形式...
  6. 使用 case when进行行列转换
  7. java set方法不生效_使您的Java 8方法引用生效
  8. 【OpenCV 例程200篇】88. 频率域拉普拉斯高通滤波
  9. 设置开机ceph自动map rbd块设备
  10. Linux 命令(28)—— tee 命令
  11. 【转载】架构师的行为准则(三)
  12. 毕业季海报设计素材图片大全,送给毕业生们最好的毕业季祝福语文案
  13. matlab 万能实用的线性曲线拟合方法
  14. bzoj3097 Hash Killer I
  15. QEMU 安装与使用
  16. Shiro源码-创建subject
  17. 空间想象力差学计算机,空间思维想象力差怎么办
  18. 学者该如何快速入门Python?内附十年Python程序员详细学习攻略
  19. 打印U盘文件计算机有记录吗,技术员教你win10系统查看打印机打印历史记录的问题...
  20. 一文学会网络分析——Co-occurrence网络图在R中的实现

热门文章

  1. Android Camera2 拉伸问题
  2. 一篇文章带你深入理解什么是负载测试
  3. 大学计算机软件应用基础提纲,《大学计算机应用基础》课程教学大纲.doc
  4. Linux系统安装向日葵远程协助
  5. 2023北方民族大学计算机考研信息汇总
  6. JS日期方法操作大全,看这篇就够了
  7. 使用Thumbnails工具对图片进行缩放,压缩
  8. PCTP考试学习笔记之一:深入TIDB体系架构(上)
  9. 东南大学计算机2020初试成绩公布,东南大学2020考研复试分数线已公布
  10. jdk8安装教程及环境变量配置