Come on和我一起做基于深度学习的缺陷检测一(数据准备)

2023-11-16


这里有几句话要说:

  1. 这个项目会持续更新,由于要忙于毕业答辩和论文修改,更新时间不定;
  2. 由于本人研三,今年毕业要去工作,可能会出现拖更的现象;
  3. 我把以前Python-OpenCV的相关博客删除了,因为这个OPENCV更新太快,发现有的已经没啥作用了,以后的博客尽量用矩阵运算的形式来编写代码。

数据集的制作

这里数据集用的是我博客的数据集==>织物疵点数据集,选择这个数据集是因为以下两点原因:

  1. 很多人都问我能不能进行深度学习的训练,我想试试能不能;
  2. 网上现有的数据集关于缺陷检测的数据量都很少,我在下载了一部分开源的数据集,哪天我整理好,把链接发出来。

数据标注

首先要明白,缺陷检测是根据检测要求进行标注的,大致分为以下几种情况:

  1. 检测是否有缺陷,就像我们熟悉的猫狗识别,实际上是个二分类问题;
  2. 检测是否有缺陷,并分类,就像是手写数字识别,你要知道缺陷是啥就OK;
  3. 检测是否有缺陷,分类并定位。这就像是YoLo系列和FasterRcnn一样,你不光要知道是啥,还要告诉我它在哪。

这里呢,我准备一步到位,直接实现检测是否有缺陷,分类并定位。
数据集要实现分类定位,首先要做的就是数据的标注,这里的标注工具我用的是,精灵标注助手,下载戳 精灵标注助手,至于为啥不用LabelImg,就是个人喜好了。
由于我的数据集是包含粗条纹和方格布的,为了给增加电脑的信心,这里就不用这两个类型的了,把纯色的和复合色的布匹通过截图软件进行图像截取,这里我截取的是512x512大小,其中,对每张含有疵点的图像进行不同位置的截取,每张图像截取两张。费尽九牛二虎之力终于截完了所有的图像,一共得到了2728张图像。其中每类疵点包含的数据数量如下:

疵点类别 数目 命名
断纱 308 DuanSha
带纱 425 DaiSha
脱纱 668 TuoSha
破洞 112 PoDong
污渍 422 WuZi
棉球 184 MianQiu
正常 609 Normal

可以看出数据类别出现了不平衡的问题,不过这现在对我来说不重要。先是根据命名把截图改个名字,代码直接放上,(这个代码好像是在网上copy的,好久之前的就忘记了)

import os

class BatchRename():
    '''
    批量重命名文件夹中的图片文件
    '''
    def __init__(self):
        self.path = 'E:/Learn/dataset/Making_dataset/Normal'  # 表示需要命名处理的文件夹

    def rename(self):
        filelist = os.listdir(self.path)  # 获取文件路径
        total_num = len(filelist)  # 获取文件长度(个数)
        i = 1  # 表示文件的命名是从1开始的
        for item in filelist:
            if item.endswith('.png'):  # 初始的图片的格式为jpg格式的(或者源文件是png格式及其
                # 他格式,后面的转换格式就可以调整为自己需要的格式即可)
                src = os.path.join(os.path.abspath(self.path), item)
                dst = os.path.join(os.path.abspath(self.path), 'Normal_0' + str(i) + '.jpg')  # 处理后的格式也为jpg格式的,当然这里可以改成png格式
                # dst = os.path.join(os.path.abspath(self.path), '0000' + format(str(i), '0>3s') + '.jpg')    这种情况下的命名格式为0000000.jpg形式,可以自主定义想要的格式
                try:
                    os.rename(src, dst)
                    print('converting %s to %s ...' % (src, dst))
                    i = i + 1
                except:
                    continue
        print('total %d to rename & converted %d jpgs' % (total_num, i))

if __name__ == '__main__':
    demo = BatchRename()
    demo.rename()

这里我把它定义为 image_rename.py 文件
接下来使用精灵标注助手进行标注了,再次费尽九牛二虎之力后,完成了数据的标注。
在这里插入图片描述
这里我导出两种格式,方便后续使用,分别是 .xml.json格式。整完就是这样了。
在这里插入图片描述

数据增强(图像和xml文件同时增强)

图像数据增强的方式有很多比如图像的翻转、缩放、旋转、直方图均衡化等等,由于疵点检测不适合用颜色变换来增强图像,同时为确保增强后的图像大小依然为512x512大小的图像,所以我这里使用图像的翻转、旋转来增加数据量。这里我简单的写了个代码,我叫它image_increase.py

import numpy as np
import cv2
import math


# 图像缩放
def image_resize(image,model_type,xita_x,xita_y):
    '''
    :param image:
    :param model_type: 0:固定尺寸裁剪; model_type: 1:系数缩放;
    :param xita_x:
    :param xita_y:
    :return:
    '''
    if model_type == 0:
        image_resize_1 = cv2.resize(image, (xita_x, xita_y))
    elif model_type == 1:
        image_resize_1 = cv2.resize(image,(0,0),fx=xita_x,fy=xita_y,interpolation=cv2.INTER_NEAREST)
    else:
        print('param error')
        image_resize_1 = image
    return image_resize_1


def img_rotate(image, angle):

    h, w, channels = image.shape
    # 图像长h=600,宽w=554
    anglePi = angle * math.pi / 180.0
    cosA = math.cos(anglePi)
    sinA = math.sin(anglePi)
    tanA = math.tan(anglePi)
    img_r = np.zeros((h,w, channels), dtype=np.uint8)
    center_array = np.array([[1,0,0],
                             [0,-1,0],
                             [-0.5*w,0.5*h,1]
                             ])
    i_center_array= np.array([[1,0,0],
                             [0,-1,0],
                             [0.5*w,0.5*h,1]
                             ])
    rotate_array = np.array([[cosA,-sinA,0],
                             [sinA,cosA,0],
                             [0,0,1]
                             ])
    rotate = np.dot(center_array, rotate_array)
    i_rotate = np.dot(rotate, i_center_array)

    for i in range(0, w):
        for j in range(0, h):
            # x = int(cosA*i-sinA*j-0.5*w*cosA+0.5*h*sinA+0.5*w)
            # y = int(sinA*i+cosA*j-0.5*w*sinA-0.5*h*cosA+0.5*h)
            new = np.dot(np.array([i,j,1]),i_rotate)

            x = int(new[0])
            y = int(new[1])

            if x >= 0 and x < w and y >= 0 and y < h:
                img_r[j, i] = image[y, x]

    # ------------------------------------------------------------------
    # 逆时针坐标变换
    i_rotate_array = np.array([[cosA,sinA,0],
                             [-sinA,cosA,0],
                             [0,0,1]
                             ])
    rotate_i = np.dot(center_array, i_rotate_array)
    # 直线A'B':y = tanA*x + h/(2*cosA)
    # 直线B'C':y = -1/tanA*x + w/(2*sinA)
    # 直线C'D':y = tanA*x - h/(2*cosA)
    # 直线D'A':y = -1/tanA*x - w/(2*sinA)
    # 直线B'C'与 AB 交点
    x_BC_AB = int(-(h/2-w/(2*sinA))*tanA) ; y_BC_AB = h//2
    # 直线B'C'与 BC交点
    x_BC_BC = w//2;y_BC_BC = int(-w/(2*tanA)+w/(2*sinA))

    BC_AB = np.dot(np.array([x_BC_AB, y_BC_AB, 1]), i_center_array)
    BC_BC = np.dot(np.array([x_BC_BC, y_BC_BC, 1]), i_center_array)

    img_AB = img_r[0:int(BC_BC[1]), int(BC_AB[0]):w]
    img_AB_1 = np.rot90(img_AB)
    img_AB_2 = np.rot90(img_AB_1)
    img_AB_3 = img_AB + img_AB_2
    img_r[0:int(BC_BC[1]), int(BC_AB[0]):w] = img_AB_3

    # 直线C'D'与 CD 交点
    x_CD_CD = int((-h/2+h/(2*cosA))/tanA) ; y_CD_CD = -h//2
    # 直线C'D'与 BC 交点
    x_CD_BC = w//2;y_CD_BC = int(w/2*tanA-h/(2*cosA))

    CD_CD = np.dot(np.array([x_CD_CD, y_CD_CD, 1]), i_center_array)
    CD_BC = np.dot(np.array([x_CD_BC, y_CD_BC, 1]), i_center_array)
    img_CD = img_r[int(CD_BC[1]):h, int(CD_CD[0]):w]
    img_CD_1 = np.rot90(img_CD)
    img_CD_2 = np.rot90(img_CD_1)
    img_CD_3 = img_CD + img_CD_2
    img_r[int(CD_BC[1]):h, int(CD_CD[0]):w] = img_CD_3


    # 直线D'A'与 CD 交点
    x_DA_CD = int((h / 2 - w / (2 * sinA)) * tanA); y_DA_CD = -h // 2
    # 直线D'A'与 AD 交点
    x_DA_AD = -w // 2; y_DA_AD = int(w / (2 * tanA) - w / (2 * sinA))

    DA_CD = np.dot(np.array([x_DA_CD, y_DA_CD, 1]), i_center_array)
    DA_AD = np.dot(np.array([x_DA_AD, y_DA_AD, 1]), i_center_array)
    print(DA_CD, DA_AD)
    img_DA = img_r[int(DA_AD[1]):h, 0:int(DA_CD[0])]
    img_DA_1 = np.rot90(img_DA)
    img_DA_2 = np.rot90(img_DA_1)
    img_DA_3 = img_DA + img_DA_2
    img_r[int(DA_AD[1]):h, 0:int(DA_CD[0])] = img_DA_3

    # 直线A'B'与 AB 交点
    x_AB_AB = int((h / 2 - h / (2 * cosA)) / tanA); y_AB_AB = h // 2
    # 直线A'B'与 AD 交点
    x_AB_AD = -w // 2; y_AB_AD = int(-w / 2 * tanA + h / (2 * cosA))

    AB_AB = np.dot(np.array([x_AB_AB, y_AB_AB, 1]), i_center_array)
    AB_AD = np.dot(np.array([x_AB_AD, y_AB_AD, 1]), i_center_array)
    print(AB_AB, AB_AD)
    img_AB = img_r[0:int(AB_AD[1]), 0:int(AB_AB[0])]
    img_AB_1 = np.rot90(img_AB)
    img_AB_2 = np.rot90(img_AB_1)
    img_AB_3 = img_AB + img_AB_2
    img_r[0:int(AB_AD[1]), 0:int(AB_AB[0])] = img_AB_3

    return img_r

def image_flip(image, thea):
    '''
    :param image: 输入图像
    :param thea: thea:1=水平翻转;thea:0=垂直翻转;thea:-1=镜像翻转;
    :return: img
    '''
    if thea == 0:
        # 水平翻转
        img = cv2.flip(image, thea)
    elif thea == 1:
        # 垂直翻转
        img = cv2.flip(image, thea)
    elif thea == -1:
        # 垂直翻转
        img = cv2.flip(image, thea)
    else:
        img = image
        print('thea error!')
    return img

这里图像旋转部分是根据我的一篇博客‘图像任你转,黑边不再现’该的,这个方法对于旋转非直角的角度还是会出现边缘化的现象,但是对于直角角度的旋转并没有什么影响。
如果你这么做,你应该先增强数据,然后在标注。但是作为一名懒惰的研究生,肯定不做这么复杂的事情。
逆向思维,我们数据增强后也是要得到.xml格式的文件,但是根据你图像增强的方式,xml中坐标值也是有规律的。本着这个想法,先看看xml文件中都有啥。
在这里插入图片描述
就是这个东西了,想修改这个东西,得先弄清楚这个玩意用Python怎么写,在网上找找资料,自己整了个
Pytho_create_xml.py
文件,

# -*- coding: utf-8 -*-
from lxml import etree
import numpy as np
import xml.etree.ElementTree as ET
import math
import os
# 创建 xml格式 文件
def creat_xml(xml_file, x, y, w, h):
    """
    新建xml文件
    :param xml_file: xml
    :param x: xmin
    :param y: ymin
    :param w: 宽
    :param h: 高
    :return:
    """
    doc = etree.Element("doc")  # 创建根节点 doc
    path = etree.SubElement(doc, "path")
    path.text = "E:\Learn\dataset\数据集制作\带纱\DaiSha_01.jpg"  # 为节点 path 添加描述信息

    outputs = etree.SubElement(doc, "outputs")  # 创建 doc 节点的子节点 outputs
    object = etree.SubElement(outputs, "object")  # 创建 outputs节点的子节点 object
    item = etree.SubElement(object, "item")  # 创建 object 节点的子节点 item
    name = etree.SubElement(item, "name") # 创建 item 节点的子节点 name
    name.text = "DaiSha"
    bndbox = etree.SubElement(item, "bndbox")
    xmin = etree.SubElement(bndbox, "xmin")
    xmin.text = str(x)
    ymin = etree.SubElement(bndbox, "ymin")
    ymin.text = str(y)
    xmax = etree.SubElement(bndbox, "xmax")
    xmax.text = str(x + w)
    ymax = etree.SubElement(bndbox, "ymax")
    ymax.text = str(y + h)
    time_labeled = etree.SubElement(doc, 'time_labelde')
    time_labeled.text = '1588735336809'
    label = etree.SubElement(doc, 'label')
    label.text = 'true'
    size = etree.SubElement(doc, 'size')
    width = etree.SubElement(size, 'width')
    width.text = '512'
    height = etree.SubElement(size, 'height')
    height.text = '512'
    depth = etree.SubElement(size, 'depth')
    depth.text = '3'
    tree = etree.ElementTree(doc)
    tree.write(xml_file, pretty_print=True, xml_declaration=False, encoding='utf-8')
    return xml_file

xx = creat_xml('ss.xml', 32, 120, 80, 80)

用这个写完,生成的文件就和那个图片内容一样了。 既然知道怎么写了,那怎么改也就不难了,经过我的‘苦心专研’,整出来了 image_xml_increase.py。先说说这个文件的功能,同时对图像和标注文件进行增强,增强方式包括:顺时针旋转90°,180°,270°,逆时针旋转-90°,-180°,-270°;图像水平翻转、垂直翻转、镜像翻转。并且得到对应的标注xml文件。

# -*- coding: utf-8 -*-
# 作者:大大玮在路上
# 图像和对应的xml文件扩充
import numpy as np
import xml.etree.ElementTree as ET
import math
import os
from tqdm import tqdm
import cv2

# 编辑 xml 格式文件
def edit_xml(xml_file, model, angle):
    '''
        修改xml文件,对于数据标注来说,我们改的格式主要就是以下两点:
    1. name
    2. bndbox
    因此,封好的函数主要也是围绕这两个变化而实现的功能
    1. 图像标注完成后,经图像旋转、翻转后的新的xml文件的生成.
    这里我是做缺陷检测的,所以说缩放、增强对比度、直方图均衡化之类的对我没啥用,我就不写了
    :param xml_file:xml文件的路径
    :
    :return:
    :param xml_file: 文件的路径
    :param model: 图像变换模式,rotate:图像旋转,angle可以为90,180,270,-90,-180,-270
                               flip:图像翻转,angle可以为0:水平翻转;1:垂直翻转;-1:先水平后垂直翻转
    :param angle:
    :return:
    '''
    global x, y, x_w, y_h, w_total, h_total
    tree = ET.parse(xml_file)  # 读取 xml 文件
    tree.getroot()
    for size in tree.iter('size'):
        for w in size.iter('width'):
            w_total = int(w.text)
        for h in size.iter('height'):
            h_total = int(h.text)

    for bndbox in tree.iter('bndbox'):
        for xmin in bndbox.iter('xmin'):
            x = int(xmin.text)
        for ymin in bndbox.iter('ymin'):
            y = int(ymin.text)
        for xmax in bndbox.iter('xmax'):
            x_w = int(xmax.text)
        for ymax in bndbox.iter('ymax'):
            y_h = int(ymax.text)

    w_1 = x_w - x
    h_1 = y_h - y
    anglePi = angle * math.pi / 180.0
    cosA = math.cos(anglePi)
    sinA = math.sin(anglePi)
    print( x, y, x_w, y_h, w_total, h_total)
    center_array = np.array([[1, 0, 0],
                             [0, -1, 0],
                             [-0.5 * w_total, 0.5 * h_total, 1]
                             ])
    i_center_array = np.array([[1, 0, 0],
                               [0, -1, 0],
                               [0.5 * w_total, 0.5 * h_total, 1]
                               ])
    rotate_array = np.array([[cosA, sinA, 0],
                             [-sinA, cosA, 0],
                             [0, 0, 1]
                             ])

    rotate = np.dot(center_array, rotate_array)
    i_rotate = np.dot(rotate, i_center_array)
    # 逆时针旋转
    if model == 'rotate':
        new_min = np.dot(np.array([x, y, 1]), i_rotate)
        x_new = new_min[0]
        y_new = new_min[1]
        print(angle)

        if angle == 90 or angle == -270:
            x_min = x_new
            y_min = y_new - w_1
            x_max = x_new + h_1
            y_max = y_new
        elif angle == 180 or angle == -180:
            x_min = x_new - w_1
            y_min = y_new - h_1
            x_max = x_new
            y_max = y_new

        elif angle == 270 or angle == -90:
            x_min = x_new - h_1
            y_min = y_new
            x_max = x_new
            y_max = y_new + w_1

        for bndbox in tree.iter('bndbox'):
            for xmin in bndbox.iter('xmin'):
                xmin.text = str(int(x_min))
            for ymin in bndbox.iter('ymin'):
                ymin.text = str(int(y_min))
            for xmax in bndbox.iter('xmax'):
                xmax.text = str(int(x_max))
            for ymax in bndbox.iter('ymax'):
                ymax.text = str(int(y_max))

    # 镜像翻转
    elif model == 'flip':
        new_min = np.dot(np.array([x, y, 1]), center_array)
        x_new = new_min[0]
        y_new = new_min[1]
        # 水平翻转
        if angle == 0:
            x_min = -x_new - w_1
            y_min = y_new
            x_max = -x_new
            y_max = y_new - h_1
        # 垂直翻转
        elif angle == 1:
            x_min = x_new
            y_min = -y_new + h_1
            x_max = x_new + w_1
            y_max = -y_new
        # 先水平后垂直
        elif angle == -1:
            x_min = -x_new - w_1
            y_min = -y_new + h_1
            x_max = -x_new
            y_max = -y_new
        result_min = np.dot(np.array([x_min, y_min, 1]), i_center_array)
        result_max = np.dot(np.array([x_max, y_max, 1]), i_center_array)

        print(result_max,result_min)
        for bndbox in tree.iter('bndbox'):
            for xmin in bndbox.iter('xmin'):
                xmin.text = str(int(result_min[0]))
                print(str(int(result_min[0])))
            for ymin in bndbox.iter('ymin'):
                ymin.text = str(int(result_min[1]))
            for xmax in bndbox.iter('xmax'):
                xmax.text = str(int(result_max[0]))
            for ymax in bndbox.iter('ymax'):
                ymax.text = str(int(result_max[1]))
    else:
        print('Model Error!!')
    path = 'E:/Learn/dataset/Making_dataset/'  # 文件存储的路径
    name = os.path.basename(xml_file)
    file_name = name.split('.')[0]
    tree.write(path + file_name + str('_') + model + str('_') + str(angle) + '.xml')

def image_increase(image_path, model, angle):
    '''

    :param image_path:输入图像
    :param model:rotate:图像旋转,flip:图像翻转
    :param angle: 90,180,270,-90,-180,-270,0,1,-1
    :return:
    '''

    image = cv2.imread(image_path)

    angle_rotate = [90, 180, 270, -90, -180, -270]
    angle_flip = [0, 1, -1]

    height, width, channels = image.shape
    if model == 'rotate':
        angle_rotate = set(angle_rotate)
        if angle in angle_rotate:

            matRotate = cv2.getRotationMatrix2D((height * 0.5, width * 0.5), angle, 1)

            img = cv2.warpAffine(image, matRotate, (height, width))

    elif model == 'flip':
        angle_flip = set(angle_flip)
        if angle in angle_flip:

            img = cv2.flip(image, angle)

    else:
        img = image
        print('The angle number is error! Please input True-angle!')
    path = 'E:\Learn\dataset\Making_dataset/'  # 文件存储的路径
    name = os.path.basename(image_path)
    file_name = name.split('.')[0]

    cv2.imwrite(path + file_name + str('_') + model + str('_') + str(angle) + '.jpg', img)
if __name__ == '__main__':
    # 这里要保证图像增强和对应的xml标注文件对应,所以命名两个变量
    model = 'flip'
    angle = -1
    # 标注文件增强
    path_xml = r'E:\Learn\dataset\making_dataset\DaiSha_out_xml/'
    xml_files = [os.path.join(rootdir, file) for rootdir, _, files in os.walk(path_xml) for file in files if
                 (file.endswith('.xml'))]
    for pathed in xml_files:
        head = os.path.join(pathed)
        edit_xml(pathed, model, angle)
    # 图像增强
    path_image = r'E:/Learn/dataset/Making_dataset/DaiSha/'
    img_files = [os.path.join(rootdir, file) for rootdir, _, files in os.walk(path_image) for file in files if
                 (file.endswith('.jpg'))]
    for pathed in img_files:
        head = os.path.join(pathed)
        image_increase(head, model, angle)

需要注意的是,为了区分数据增强后数据和原始数据,这里命名方式后面添加了增强方式,例如,原文件DaiSha_01.jpg,经过镜像翻转后的名字为DaiSha_01_flip_-1.jpg
我以水平翻转为例,这里就得到了增强后的jpg和xml文件,运行一下上面的代码,看下图,兴奋一下。
在这里插入图片描述
再来看看直观的对比图
在这里插入图片描述
原图
在这里插入图片描述
翻转后的图像,再来看看xml文件的变化
在这里插入图片描述
这是原来的,
在这里插入图片描述
这是镜像翻转之后的。有的细心的小伙伴可能看到,文件路径没换啊,其实这个路径不是很重要,想换的,稍微改一下就可以了。
想一想,这一顿操作下来,数据可以扩充六倍啊。至于多少有效的数据我就不知道了,这个后期做完我再慢慢验证。
还有一点,有的小伙伴可能认为这个弄成灰度图不是更好吗,其实我也是这么认为的,我先拿三通道的图像试试,如果想直接用灰度图的话,把图像通过函数一变,xml文件中的赋值改为1就可以了。
以上就是数据集制作的全部内容了,喜欢的小伙伴点个赞啥的,要不总感觉自己在自言自语,哈哈哈。
下一个博客的名字就叫做数据的转换和读取
未完待续。。。。。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Come on和我一起做基于深度学习的缺陷检测一(数据准备) 的相关文章

  • 使用 XMLStarlet(图像注释)将值连接到现有 xml 属性

    我正在使用 xml 来注释图像 我正在使用 xmlstarlet 和 unix bash 命令 但当我尝试将值附加到现有 xml 属性值时遇到一些问题 例如 我有
  • Python 切片对象和 __getitem__

    python 中是否有内部的东西来处理传递给的参数 getitem 不同 并自动转换start stop step构造成切片 这是我的意思的演示 class ExampleClass object def getitem self args
  • 使用python查找txt文件中字母出现的次数

    我需要从 txt 文件中读取该字母并打印 txt 文件中出现的次数 到目前为止 我已经能够在一行中打印内容 但计数有问题 有人可以指导吗 infile open grades txt content infile read for char
  • 稀有对象的 python 类型注释,例如 psycopg2 对象

    我了解内置类型 但是我如何指定稀有对象 例如数据库连接对象 def get connection and cursor gt tuple psycopg2 extensions cursor psycopg2 extensions conn
  • 使用 django-rest-framework 设置对象级权限

    尝试使用 django rest framework 最干净 最规范地管理 django guardian 对象级权限 我想将对象的读取权限 module view object 分配给在执行 POST 时发出请求的用户 我的基于阶级的观点
  • 在Python中从大文件中搜索单词列表

    我是新蟒蛇 我有一个单词列表和一个非常大的文件 我想删除文件中包含单词列表中的单词的行 单词列表按排序给出 并且可以在初始化期间输入 我正在努力寻找解决这个问题的最佳方法 我现在正在进行线性搜索 这花费了太多时间 有什么建议么 您可以使用i
  • 从 Azure ML 实验中访问 Azure Blob 存储

    Azure ML 实验提供了通过以下方式读取 CSV 文件并将其写入 Azure Blob 存储的方法 Reader and Writer模块 但是 我需要将 JSON 文件写入 blob 存储 由于没有模块可以执行此操作 因此我尝试在Ex
  • 通过 post 使用 php 发送 XML

    我知道有很多类似的问题 但我尝试过摆弄所有的解决方案 但似乎无法使其发挥作用 我正在尝试将 xml 直接发布到 Web 服务并获得响应 从技术上讲 我正在尝试连接到freightquote com 您可以在右上角找到该文档this http
  • 如何过滤 Pandas GroupBy 对象并获取 GroupBy 对象?

    当对 Pandas groupby 操作的结果执行过滤时 它返回一个数据帧 但假设我想执行进一步的分组计算 我必须再次调用 groupby 这似乎有点绕 有更惯用的方法吗 EDIT 为了说明我在说什么 我们无耻地从 Pandas 文档中窃取
  • 协程从未被等待

    我正在使用一个简单的上下文管理器 其中包含一个异步循环 class Runner def init self self loop asyncio get event loop def enter self return self def e
  • Python将文本文件解析为嵌套字典

    考虑以下数据结构 HEADER1 key value key value HEADER2 key value key value HEADER3 key value HEADER4 key value key value 原始数据中没有缩进
  • 查找 Pandas DF 行中的最短日期并创建新列

    我有一个包含多个日期的表 有些日期将为 NaN 我需要找到最旧的日期 所以一行可能有 DATE MODIFIED WITHDRAWN DATE SOLD DATE STATUS DATE 等 因此 对于每一行 一个或多个字段中都会有一个日期
  • 给定一个排序数组,就地删除重复项,使每个元素仅出现一次并返回新长度

    完整的问题 我开始在线学习 python 但对这个标记为简单的问题有疑问 给定一个排序数组 就地删除重复项 使得每个 元素只出现一次并返回新的长度 不分配 另一个数组的额外空间 您必须通过修改输入来完成此操作 数组就地 具有 O 1 额外内
  • Ubuntu systemd 自定义服务因 python 脚本而失败

    希望获得有关 Ubuntu 中的 systemd 守护进程服务的一些帮助 我写了一个 python 脚本来禁用 Dell XPS 上的触摸屏 这更像是一个问题 而不是一个有用的功能 该脚本可以工作 但我不想一直启动它 这就是为什么我想到编写
  • 在Raspberry pi上升级skimage版本

    我已经使用 Raspberry Pi 2 上的 synaptic 包管理器安装了 python 包 然而 skimage 模块版本 0 6 是 synaptic 中最新的可用版本 有人可以指导我如何将其升级到0 11 因为旧版本中缺少某些功
  • 为什么 __dict__ 和 __weakref__ 类从未在 Python 中重新定义?

    类创建似乎从来没有re 定义 dict and weakref class属性 即 如果它们已经存在于超类的字典中 则它们不会添加到其子类的字典中 但始终re 定义 doc and module class属性 为什么 gt gt gt c
  • 如何将带有参数的Python装饰器实现为类?

    我正在尝试实现一个接受一些参数的装饰器 通常带有参数的装饰器被实现为双重嵌套闭包 如下所示 def mydecorator param1 param2 do something with params def wrapper fn def
  • 如何给URL添加变量?

    我正在尝试从网站收集数据 我有一个 Excel 文件 其中包含该网站的所有不同扩展名 F i www example com example2 我有一个脚本可以成功从网站中提取 HTML 但现在我想为所有扩展自动执行此操作 然而 当我说 s
  • 如何从namedtuple实例列表创建pandas DataFrame(带有索引或多索引)?

    简单的例子 from collections import namedtuple import pandas Price namedtuple Price ticker date price a Price GE 2010 01 01 30
  • 用于插入或替换 URL 参数的 Django 模板标签

    有人知道 Django 模板标签可以获取当前路径和查询字符串并插入或替换查询字符串值吗 例如向 some custom path q how now brown cow page 3 filter person 发出请求 电话 urlpar

随机推荐

  • Python之NumPy(axis=0/1/2...)的透彻理解

    前言 在numpy的使用中 对axis的使用总是会产生疑问 如np sum函数 在多维情况下 axis不同的取值应该做怎样的运算呢 返回的是什么形状的数组呢 在网上查了很多资料 总是似懂非懂 查阅了官方文件 以及多次试验后 我总结出一种能深
  • [ZYNQ随笔] uboot移植中bitstream比特流加载问题:zynq_validate_bitstream: Bitstream is not validated yet

    问题介绍 由于项目设计需要 需要频繁的更换比特流文件 之前使用petalinux生成的boot bin每次都需要合并比特流 比较麻烦 遂换了一个uboot版本 米联客默认的u boot 将bitstream放到了独立于boot bin的文件
  • 经验教训

    最近有一个项目基于STM32F446ZE MCU使用FREERTOS操作系统开发 之前有部分功能代码是基于MCU裸机开发的 移植过程种发现程序老出错 DEBUG模式条件发现程序停在了HardFault Handler中断服务程序中 查看对应
  • 对角矩阵np.diag()

    np diag 是 NumPy 库中的一个函数 用于创建一个对角矩阵或从一个矩阵中提取对角线元素 具体来说 np diag 可以接受以下两种参数 一个一维数组 将其转换为一个对角矩阵 数组中的元素将成为对角线上的元素 例如 np diag
  • STM3232 GPIO的配置寄存器(为了移植IIC)

    参考 https blog csdn net qq 45539458 article details 129481019 https blog csdn net weixin 43314829 article details 1255734
  • 公共IP地址、私有IP地址、NAT技术

    1 公共IP地址和私有IP地址的区别 在 Internet 上存在数量有限的 IP 地址 这些能在Intenet上使用的地址被称为公共IP地址 且IP地址必须是唯一的 但是私有IP地址就是例外 这些IP地址供LAN网络中使用 同时它们可以在
  • Win7连接共享打印机时,报 0x00000bcb 错误

    打印服务器添了台 DocuCentre VI C3371 富士施乐3371打印机 问题描述 Win8 1 Win10等系统均能正常连接 部分 Win7 客户端连接时 报0x00000bcb错误 解决方法 后来桌面小哥找到了解决方法 Win7
  • 带头节点链表的操作使用讲解

    带头结点链表 链表一共具有创建 增添 删除 查找四种基本操作 接下来会对这四种操作进行挨个讲解 在此之前首先提供链表结点 初始化链表 删除链表的代码 链表结点 每一个节点都包含有一个数据以及指向下一结点的指针 以及定义一个链表的头指针 ty
  • 【Java八股文总结】之面试题(二)

    文章目录 面试题 一 几种锁的区别 1 synchronized 和ReentrantLock的区别 二 Java高级 1 反射 1 反射的应用场合 2 Java反射API 3 反射使用步骤 获取Class 对象 调用对象方法 4 获取Cl
  • shell脚本学习笔记2

    小试牛刀 文章目录 小试牛刀 1 7 别名 1 8 获取并设置日期及延时 1 9 调试脚本 1 10 函数和参数 1 11 将一个命令的输出发送给另一个命令 1 11 1 利用子 shell 生成一个独立的进程 1 11 2 通过引用子sh
  • 轻型数据库SQLite与Android实例

    SQLite 是一款轻型的数据库 是遵守ACID的关联式数据库管理系统 它的设计目标是嵌入式的 而且目前已经在很多嵌入式产品中使用了它 它占用资源非常的低 在嵌入式设备中 可能只需要几百K的内存就够了 它能够支持Windows Linux
  • 双口RAM及Vivado RAM IP核的使用

    目录 1 双口RAM概述 2 Vivado 双口RAM IP核 2 1 Block Memory Generator概述 2 2 真双口RAM的设置 2 2 1 Basic设置 2 2 2 Port设置 3 双口RAM例程 4 仿真 4 后
  • 当UNet遇见ResNet会发生什么?

    点击上方 小白学视觉 选择加 星标 或 置顶 重磅干货 第一时间送达 1 前言 这篇文章主要以几篇经典的分割论文为切入点 浅谈一下当Unet遇见ResNet会发生什么 2 UNet 首先回顾一下UNet UNet的结构如下图所示 UNet
  • ubuntu下x86架构中交叉编译arm架构的程序

    ubuntu下x86架构中交叉编译arm架构的程序 交叉编译工具链安装 操作步骤 我们平时使用的大多数电脑都是英特尔的处理器 使用的是x86架构 因此仿真过程的代码是在x86架构的处理器运行的 但是当我们需要将程序部署到终端用于实物调试时
  • 工作小记:异步线程中事务不生效的问题

    在日常的开发中经常会遇到在线程池或者异常异步中执行自己的业务代码 lz最近在开发业务代码的时候也遇到一个类型的需求 因为请求处理的时间比较长 在设计接口的时候要求异步完成 直接上业务代码 executeOccupyStock 方法也添加了事
  • python并行计算(完结篇):并行方法总结

    转自 https zhuanlan zhihu com p 46678895 由于python相当易学易用 现在python也较多地用于有大量的计算需求的任务 本文介绍几个并行模块 以及实现程序并行的入门技术 本文比较枯燥 主要是为后面上工
  • 2023版最新最全React面试题

    React 作为前端使用最多的框架 必然是面试的重点 我们接下来主要从 React 的使用方式 源码层面和周边生态 如 redux react router 等 等几个方便来进行总结 1 使用方式上 这里主要考察的是 在开发使用过程中 对
  • 均匀分布的期望和方差的推导_概率论中均匀分布的数学期望和方差该怎么求啊?...

    展开全部 数学期望是分布区间e68a8462616964757a686964616f31333431343065左右两端和的平均值 方差为分布区间左右两端差值平方的十二分之一 均匀分布是经常遇到的一种分布 其主要特点是 测量值在某一范围中各
  • Ubuntu下安装Matlab步骤

    1 下载matlab iso镜像文件 可以从verycd上下载 搜索matlab unix版可得到 我下的是2010a 2 打开终端 输入sudo mkdir mnt temp 建立临时文件夹存放装载后的iso文件 再输入 sudo mou
  • Come on和我一起做基于深度学习的缺陷检测一(数据准备)

    基于深度学习的织物疵点检测 数据集的制作 数据标注 数据增强 图像和xml文件同时增强 这里有几句话要说 这个项目会持续更新 由于要忙于毕业答辩和论文修改 更新时间不定 由于本人研三 今年毕业要去工作 可能会出现拖更的现象 我把以前Pyth