目标检测数据预处理——非宫格与宫格混合拼图(大宽高比图片)

news2024/11/23 22:29:01

之前一直用的是宫格的正方形拼图,但比如对“人”框的截图是这种高宽高比的长方形图片,按照最大边resize最小边等比例缩放后放入宫格中对造成最小边resize太多,整体图片缩小很多。所以本片专门针对高宽高比的图片拼图进行编辑。

本篇的拼图方式有2种:分别是长方形拼图和正方形拼图(即宫格拼图)。其中正方形拼图有4种,从1×1到4×4;长方形拼图有4种,分别是1×2、2×1、2×3、3×2,根据宽高比在哪个范围内以及横向或者纵向来判断按照对应的方式进行拼图。判断流程如下:

Created with Raphaël 2.3.0 输入图片 max_len = max(img_h, img_w) max_len == img_w ? rate = img_w / img_h, state = "水平" rate = img_h / img_w, state = "垂直" yes no
state为水平
state为垂直
state为水平
state为垂直
state为水平
state为垂直
state为水平
state为垂直
rate和state
rate<1.2
从1*1到4*4
1.2 <= rate <= 1.3
1*1
3*2
2*3
1.3 < rate < 1.7
3*2
2*3
1.7 <= rate <= 1.8
3*2和2*1
2*3和1*2
rate > 1.8
2*1
1*2

n×n的这里不再贴图演示,这里演示非宫格的拼图效果:
1×2:
在这里插入图片描述
2×1:
在这里插入图片描述
2×3:
在这里插入图片描述
3×2:
在这里插入图片描述
若是上面的流程图判断不是很清晰的话,可以看下面的数轴更加直观简单:
在这里插入图片描述
因为1.2到1.3与1.7到1.8是两边的中间区域,所以让这区间的图片同时resize成两个size的图片。

'''
5 size
1*1 1*2 2*1 2*3 3*2
'''
import codecs
from genericpath import exists
import random
import PIL.Image as Image
import os
import cv2
import json2txt
import sys
sys.path.append("/data/cch/拼图代码/format_transform")
import modeTxt
import shutil
import cut_bbox

# 图像拼接
def image_compose(idx, ori_tmp, num, save_path, gt_resized_path, bg_resized_path, imgsize, yr, xr, xs, ys):
    to_image = Image.new('RGB', (imgsize, imgsize)) #创建一个新图
    
    for y in range(yr):
        for x in range(xr):
            index = y*xr + x
            if index >= len(ori_tmp):
                break
            open_path = [gt_resized_path, bg_resized_path]
            for op in open_path:
                if os.path.exists(os.path.join(op, ori_tmp[index])):
                    to_image.paste(Image.open(os.path.join(op, ori_tmp[index])), (
                        int(x * xs), int(y * ys)))
                    break
                else:
                    continue
    new_name = os.path.join(save_path, "2022workcloth_pedestrain_" + str(idx) + "_" + str(num) + ".jpg")
    if xr == yr:
        new_name = os.path.join(save_path, "2022workcloth_square_" + str(idx) + "_" + str(num) + ".jpg")
    to_image.save(new_name) # 保存新图
    # print(new_name)
    return new_name

# 标签拼接
def labels_merge(ori_tmp, new_name, txt_resized_path, txt_pintu_path, yr, xr, xs, ys):
    data = ""
    for y in range(yr):
        for x in range(xr):
            index = y*xr + x
            if index >= len(ori_tmp):
                break
            txt_path = os.path.join(txt_resized_path, ori_tmp[index].split(".")[0] + ".txt")
            try:
                os.path.exists(txt_path)
            except:
                print(txt_path, "file not exists!")
            if os.path.exists(txt_path):
                with codecs.open(txt_path, 'r', encoding='utf-8',errors='ignore') as f1:
                    for line in f1.readlines():
                        line = line.strip('\n')
                        a = line.split(' ')
                        a[2] = str(float(a[2]) + (x * xs))
                        a[3] = str(float(a[3]) + (y * ys))
                        a[4] = str(float(a[4]) + (x * xs))
                        a[5] = str(float(a[5]) + (y * ys))
                        b =a[0] + ' ' + a[1] + ' ' + a[2] + ' ' + a[3] + ' ' + a[4] + ' ' + a[5]
                        data += b + "\n"

    write_path = os.path.join(txt_pintu_path, os.path.splitext(new_name)[0].split("/")[-1] + ".txt")
    with open(write_path, 'w', encoding='utf-8') as f2:    
        f2.writelines(data)
 
 # 涂黑处理
def pintu2black(txt_pintu_path, save_path, label_black, label_del, to_black_num, to_black_min_num):
    files = os.listdir(txt_pintu_path)
    for file in files:
        img_path = os.path.join(save_path, os.path.splitext(file)[0] + ".jpg")
        img_origal = cv2.imread(img_path)
        data = ""
        with codecs.open(txt_pintu_path+"/"+file, encoding="utf-8", errors="ignore") as f1:
            for line in f1.readlines():
                line = line.strip("\n")
                a = line.split(" ")
                xmin = int(eval(a[2]))
                ymin = int(eval(a[3]))
                xmax = int(eval(a[4]))
                ymax = int(eval(a[5]))
                if ((xmax - xmin < to_black_num) and (ymax - ymin < to_black_num)) or \
                    ((xmax - xmin < to_black_min_num) or (ymax - ymin < to_black_min_num)) \
                    or a[1] in label_black:
                    img_origal[ymin:ymax, xmin:xmax, :] = (0, 0, 0)
                    cv2.imwrite(img_path, img_origal)
                    line = ""
                if a[1] in label_del:
                    line = ""
                if line:
                    data += line + "\n"
        with open(txt_pintu_path+"/"+file, 'w', encoding='utf-8') as f2:    
            f2.writelines(data)
        # print(data)

def gt_distribute(imgSave_path, ori, ori_spec, gt_resized_path, txt_path, gt_range):
    image_names = os.listdir(imgSave_path)
    for image_name in image_names:
        imgPath = os.path.join(imgSave_path, image_name)
        img = cv2.imread(imgPath)
        [img_h, img_w, _] = img.shape
        max_len = max(img_h, img_w)
        print(image_name, max_len)
        state = ""
        rate = 0
        if max_len == img_w:
            state = "horizontal"
            rate = img_w / img_h
        else:
            state = "vertical"
            rate = img_h / img_w

        if rate < 1.2:
            for index in range(len(gt_range)):
                if gt_range[index][0] <= max_len < gt_range[index][1]:
                    gt_resized_name = gt_resize(gt_resized_path, txt_path, image_name, img, gt_range[index][0], index+1, state, True)
                    ori_spec[index].append(gt_resized_name)
            continue
        
        # gt_resize函数的参数True为最长边resize,False为最短边resize,意在resize后的最短、最长边都不会超出格子的最短、最长边
        if 1.2 <= rate <= 1.3:
            gt_resized_name = gt_resize(gt_resized_path, txt_path, image_name, img, imgsize, 1, state, True)
            ori_spec[0].append(gt_resized_name)   # 1:1
            gt_resized_name = gt_resize(gt_resized_path, txt_path, image_name, img, int(imgsize/3), 2, state, False)
            if state == "horizontal": 
                ori[2].append(gt_resized_name)   # 2:3
            else:
                ori[3].append(gt_resized_name)   # 3:2

        if 1.3 < rate < 1.7:
            if rate <= 1.5:
                gt_resized_name = gt_resize(gt_resized_path, txt_path, image_name, img, int(imgsize/3), 1, state, False)
            else:
                gt_resized_name = gt_resize(gt_resized_path, txt_path, image_name, img, int(imgsize/2), 1, state, True)
            if state == "horizontal":
                ori[2].append(gt_resized_name)    # 2:3
            else:
                ori[3].append(gt_resized_name)    # 3:2

        if 1.7 <= rate <= 1.8:
            gt_resized_name_1 = gt_resize(gt_resized_path, txt_path, image_name, img, int(imgsize/2), 1, state, True)
            gt_resized_name_2 = gt_resize(gt_resized_path, txt_path, image_name, img, int(imgsize/2), 2, state, False)
            if state == "horizontal":
                ori[2].append(gt_resized_name_1)    # 2:3
                ori[0].append(gt_resized_name_2)    # 1:2
            else:
                ori[3].append(gt_resized_name_1)    # 3:2 
                ori[1].append(gt_resized_name_2)    # 2:1

        # if 1.8 < rate <= 2.2:
        if 1.8 < rate:
            if rate <= 2:
                gt_resized_name = gt_resize(gt_resized_path, txt_path, image_name, img, int(imgsize/2), 1, state, False)
            else:
                gt_resized_name = gt_resize(gt_resized_path, txt_path, image_name, img, imgsize, 1, state, True)
            if state == "horizontal":
                ori[0].append(gt_resized_name)    # 1:2
            else:
                ori[1].append(gt_resized_name)    # 2:1

def gt_resize(gt_resized_path, txt_path, image_name, img, img_size, x, state, flag):
    if not os.path.exists(gt_resized_path):
        os.mkdir(gt_resized_path)
    [img_h, img_w, _] = img.shape
    img_read = [0, 0, 0]
    if state == "horizontal":
        if flag:
            precent = img_size / img_w
            img_read = cv2.resize(img, (img_size, int(img_h * precent)), interpolation=cv2.INTER_CUBIC)
        else:
            precent = img_size / img_h
            img_read = cv2.resize(img, (int(img_w * precent), img_size), interpolation=cv2.INTER_CUBIC)
    else:
        if flag:
            precent = img_size / img_h
            img_read = cv2.resize(img, (int(img_w * precent), img_size), interpolation=cv2.INTER_CUBIC)
        else:
            precent = img_size / img_w
            img_read = cv2.resize(img, (img_size, int(img_h * precent)), interpolation=cv2.INTER_CUBIC)
    img_resized = gt_resized_path + "/" + image_name.split(".")[0] + "_" + str(x) + ".jpg"
    cv2.imwrite(img_resized, img_read)

    txt_name = txt_path + "/" + image_name.split(".")[0] + ".txt"
    txt_resized_name = gt_resized_path + "/" + image_name.split(".")[0] + "_" + str(x) + ".txt"
    if os.path.exists(txt_name):
        data = ""
        with codecs.open(txt_name, 'r', encoding='utf-8',errors='ignore') as f1:
            for line in f1.readlines():
                line = line.strip('\n')
                a = line.split(' ')
                a[2] = str(float(a[2]) * precent)
                a[3] = str(float(a[3]) * precent)
                a[4] = str(float(a[4]) * precent)
                a[5] = str(float(a[5]) * precent)
                b =a[0] + ' ' + a[1] + ' ' + a[2] + ' ' + a[3] + ' ' + a[4] + ' ' + a[5]
                data += b + "\n"
        with open(txt_resized_name, 'w', encoding='utf-8') as f2:    
            f2.writelines(data)
    return img_resized.split("/")[-1]

if __name__ == "__main__":
    images_path = '/data/cch/000test/images'  # 图片集地址  
    json_path = "/data/cch/000test/json"

    save_path = '/data/cch/pintu_data/test/workcloth/save1'
    tmp = "/data/cch/000test/tmp"

    #----------------------------------------------------------------
    # imgSave_path = "/data/cch/pintu_data/test/workcloth/images"
    # jsonSava_path = "/data/cch/pintu_data/test/workcloth/json"

    # if not os.path.exists(imgSave_path):
    #     os.mkdir(imgSave_path)
    # else:
    #     shutil.rmtree(imgSave_path)
    #     os.mkdir(imgSave_path)

    # if not os.path.exists(jsonSava_path):
    #     os.mkdir(jsonSava_path)
    # else:
    #     shutil.rmtree(jsonSava_path)
    #     os.mkdir(jsonSava_path)

    # cut_bbox.main(images_path, json_path, imgSave_path, ["person"], 0)   # person切图
    # cuts = os.listdir(imgSave_path)
    # for cut in cuts:
    #     if not os.path.splitext(cut)[-1] == ".json":
    #         continue
    #     json_f = os.path.join(imgSave_path, cut)
    #     shutil.move(json_f, jsonSava_path)
    #----------------------------------------------------------------

    if not os.path.exists(save_path):
        os.mkdir(save_path)
    else:
        shutil.rmtree(save_path)
        os.mkdir(save_path)

    if not os.path.exists(tmp):
        os.mkdir(tmp)
    else:
        shutil.rmtree(tmp)
        os.mkdir(tmp)
    bg_resized_path = os.path.join(tmp, "bg_resized")
    gt_resized_path = os.path.join(tmp, "gt_resized")
    txt_path = os.path.join(tmp, "txt")        # 原数据txt
    txt_pintu_path = os.path.join(tmp, "txt_pintu")

    os.mkdir(txt_path)
    os.mkdir(txt_pintu_path)

    label_black = ["other"]
    label_del = ["del"]
    imgsize = 416
    to_black_num = 15        
    to_black_min_num = 5 
    
    img_threshold = [1 / 2 * 1.2, 1 / 2 * 1.4, 1 / 6 * 1.3, 1 / 6 * 1.5]   # 每个size的图拼阈值
    img_threshold_spec = [0.3, 1 / 4 * 1.8, 1 / 9 * 1.7, 1 / 16 * 1.6]

    gt_range = [[imgsize, 10000], [int(imgsize/2), 10000], [int(imgsize/3), imgsize], [int(imgsize/4), int(imgsize/2)]]

    json2txt.main_import(jsonSava_path, txt_path)

    ori = []
    for i in range(4):
        ori.append([])    # 存放顺序 1:2 2:1 2:3 3:2

    ori_spec = []
    for i in range(4):
        ori_spec.append([])     # 存正方形小图
    
    gt_distribute(imgSave_path, ori, ori_spec, gt_resized_path, txt_path, gt_range)    # 不同size的小图放入对应容器中

    idx = 1

    for ori_m in ori_spec:       # n×n拼图
        if len(ori_m) == 0:
            idx += 1
            continue
        img_threshold_spec[idx-1] *= len(ori_m)
        if idx == 1 and img_threshold_spec[idx-1] > 80:
            img_threshold_spec[idx-1] = 80
        num = 0
        random.shuffle(ori_m)
        picknum = idx * idx
        if len(ori_m) < picknum:
            img_threshold_spec[idx-1] = 1
        index = 0
        while num < int(img_threshold_spec[idx-1]):
            ori_tmp = []
            if idx == 1:
                new_name = image_compose(idx, [ori_m[num]], num, save_path, gt_resized_path,\
                    bg_resized_path, imgsize, idx, idx, imgsize/idx, imgsize/idx)
                labels_merge([ori_m[num]], new_name, gt_resized_path, txt_pintu_path, idx,\
                    idx, imgsize/idx, imgsize/idx)

            else:
                if len(ori_m) > picknum:
                    if index >= len(ori_m):
                        random.shuffle(ori_m)
                        index = 0
                    ori_tmp = ori_m[index:index+picknum]
                    index = index + picknum
                else:
                    ori_tmp = ori_m.copy() 
                new_name = image_compose(idx, ori_tmp, num, save_path, gt_resized_path, \
                    bg_resized_path, imgsize, idx, idx, imgsize/idx, imgsize/idx) #调用函数
                labels_merge(ori_tmp, new_name, gt_resized_path, txt_pintu_path, idx,\
                    idx, imgsize/idx, imgsize/idx)

                ori_tmp.clear()
            num += 1

        print(idx, num, len(ori_m))
        idx += 1

    idx = 1
    for ori_n in ori:                  # 长方形拼图
        if len(ori_n) == 0:
            idx += 1
            continue
        # ori_path = os.path.join(save_path, "ori_" + str(idx) + ".txt")
        img_threshold[idx-1] *= len(ori_n)
        # if idx == 1 and img_threshold[idx-1] > 80:
        #     img_threshold[idx-1] = 80
        num = 0
        random.shuffle(ori_n)
        picknum = 0                      
        if idx == 1 or idx == 2:         # 1×2或2×1 拼2张
            picknum = 2
        elif idx == 3 or idx == 4:       # 2×3或3×2 拼6张
            picknum = 6
        if len(ori_n) < picknum:
            img_threshold[idx-1] = 1
        index = 0
        while num < int(img_threshold[idx-1]):
            ori_tmp = []
            [yr, xr, xs, ys] = 1, 1, 0, 0       # x,y的图片张数 小图粘贴到大图的左上角起始坐标
            # if idx == 1:
            #     new_name = image_compose(idx, [ori_n[num]], num, save_path, gt_resized_path, bg_resized_path, imgsize, yr, xr, xs, ys)
            #     labels_merge([ori_n[num]], new_name, gt_resized_path, txt_pintu_path, yr, xr, xs, ys)

            # else:
            if len(ori_n) > picknum:
                # random.sample(ori_n, picknum)
                if index >= len(ori_n):
                    random.shuffle(ori_n)
                    index = 0
                ori_tmp = ori_n[index:index+picknum]
                index = index + picknum
            else:
                ori_tmp = ori_n.copy()
            
            if idx == 1:
                [yr, xr, xs, ys] = 2, 1, imgsize, imgsize/2
            elif idx == 2:
                [yr, xr, xs, ys] = 1, 2, imgsize/2, imgsize
            elif idx == 3:
                [yr, xr, xs, ys] = 3, 2, imgsize/2, imgsize/3
            elif idx == 4:
                [yr, xr, xs, ys] = 2, 3, imgsize/3, imgsize/2
            new_name = image_compose(idx, ori_tmp, num, save_path, gt_resized_path, bg_resized_path, imgsize, yr, xr, xs, ys) #调用函数
            labels_merge(ori_tmp, new_name, gt_resized_path, txt_pintu_path, yr, xr, xs, ys)

            ori_tmp.clear()
            num += 1

        print(idx, num, len(ori_n))
        idx += 1

    pintu2black(txt_pintu_path, save_path, label_black, label_del, to_black_num, to_black_min_num)

    modeTxt.txt2darknet(txt_pintu_path, save_path, save_path)
    shutil.rmtree(tmp)
  1. 这里的拼图同样也是带文件的拼图,相应的label也会随之改变。
  2. resize的函数相较于以前版本的加了个布尔类型的flag参数,用来判断是用最大边resize还是用最小边resize,意在不会使得最大边或者最小边都不超出格子。
    比如:1.3 < rate < 1.7的图片是拼2×3的,还要再判断是否<=1.5。如果<=1.5,flag要为False即用最短边resize,因为假设格子的最长边为3最短边为2,如果此时用图片的最长边resize成3的话,最短边等比例缩放不管rate为1.3或无限接近1.5都会大于2。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/559142.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一些好用的软件推荐给你

软件一&#xff1a;nTrun nTrun 是一款非常实用的快速启动工具&#xff0c;它可以帮助用户快速启动各种常用的应用程序、网站和文件。此外&#xff0c;nTrun 还具有以下强大的功能&#xff1a; 自定义快捷键&#xff1a;用户可以根据自己的需求为每个应用程序、网站或文件设置…

Mysql链接工具

众所周知为了可以更好的操作 Mysql 数据库&#xff0c;我们都会采用远程连接工具的方式连接 Mysql 数据库&#xff0c;使用远程连接工具连接的好处在于&#xff1a; 方便远程访问&#xff1a;如果你需要在外部网络环境中访问 MySQL 数据库&#xff0c;使用远程连接工具可以方便…

《人生十二法则》- 解决人生80%不如意

法则一获胜的龙虾从不低头&#xff1a;笔直站 立&#xff0c;昂首挺胸。 法则二像照顾生病的宠物一样关心自 己&#xff1a;待己如助人。 法则三放弃损友&#xff1a;与真心希望你好的人 做朋友。 法则四战胜内心的批评家&#xff1a;和昨天的自 己比&#xff0c;别和今天的…

微软官方Microsoft Remote Desktop for Mac

microsoft-remote-desktop-for-mac 时候还是需要用到windows系统上的数据或者软件&#xff0c;除了使用第三方开发商的远程桌面工具外&#xff0c;微软公司也提供了Mac版&#xff08;iMac和MacBook&#xff09;的远程桌面软件&#xff08;Microsoft Remote Desktop&#xff09…

大数据Doris(二十五):Doris数据Binlog Load导入方式介绍

文章目录 Doris数据Binlog Load导入方式介绍 一、基本原理 二、Canal原理及配置 1、Canal同步MySQL数据原理 2、开启MySQL binlog 3、Canal配置及启动 三、Doris同步MySQL数据案例 1、MySQL中创建源表 2、Doris中创建目标表 3、创建同步作业 四、注意事项 1、关于配…

关于我用python下载两千四百四十四章保存txt这件事。。。

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 女同事最近迷上了一本书 但她又不想下载软件&#xff0c;就想要我给你下载成txt慢慢看 一看章节&#xff0c;两千四百四十四章&#xff0c;这我能答应嘛&#xff1f; 面对美女小姐姐的请求&#xff0c;我当场表示&#xff1…

看ChatGPT是如何教我爬取上千家上市公司的股票代码

现在有一个这样的需求&#xff0c;要爬取雪球网上A股的股票名称、代码和总市值这些信息并把它保存到execl表格中。对于一个新手想学习爬虫&#xff0c;如何通过chatGPT来完成这个任务呢&#xff1f; 首先&#xff0c;我们把自己的需求详细的描述向ChatGPT提问&#xff0c;问题…

数据库可视化神器,你在用哪一款呢

唠嗑部分 在我们日常开发中&#xff0c;作为开发者&#xff0c;与数据库是肯定要打交道的&#xff0c;比如MySQL&#xff0c;Oracle、sqlserver… 那么数据库可视化工具&#xff0c;你用什么呢&#xff1f;小白今天将常用地几款工具列一下&#xff0c;各位小伙伴如有喜欢的自…

亚马逊开放个人卖家验证入口?亚马逊卖家验证到底怎么搞?

亚马逊卖家账户的安全对于所有卖家来说都非常重要。如果卖家想要在亚马逊上长期稳定地发展&#xff0c;赚取更多的钱并推出更多热卖产品&#xff0c;就必须确保他们的亚马逊卖家账户安全&#xff0c;特别是一直存在的亚马逊账户验证问题。 近期&#xff0c;根据亚马逊官方披露的…

【VPX302】基于3U VPX总线架构的高性能数据预处理平台/XCKU115

板卡概述 VPX302是一款基于3U VPX总线架构的高性能数据预处理FMC载板&#xff0c;板卡具有1个FMC&#xff08;HPC&#xff09;接口&#xff0c;1个X8 GTH背板互联接口&#xff0c;可以实现1路PCIe x8&#xff1b;具有4路SRIO X4。板卡采用Xilinx的高性能Kintex UltraScale系列F…

简单实现远程访问Linux SVN服务

文章目录 前言1. Ubuntu安装SVN服务2. 修改配置文件2.1 修改svnserve.conf文件2.2 修改passwd文件2.3 修改authz文件 3. 启动svn服务4. 内网穿透4.1 安装cpolar内网穿透4.2 创建隧道映射本地端口 5. 测试公网访问6. 配置固定公网TCP端口地址6.1 保留一个固定的公网TCP端口地址6…

以太网、工业以太网和Profinet之间的区别

总的来说&#xff0c;以太网是一种局域网规范&#xff0c;工业以太网是应用于工业控制领域的以太网技术&#xff0c;Profinet是一种在工业以太网上运行的实时技术规范。 下面&#xff0c;我们来详细说说这三者的区别。 1.以太网 以太网是当今现有局域网采用的最通用的通信协议…

数据可视化-CSS3

CSS3 数据可视化 数据可视化是将数据转换为图形或图表的过程&#xff0c;以便更好地理解和分析数据。它是数据分析和数据科学中的重要组成部分&#xff0c;可以帮助人们更好地理解数据中的模式和趋势。 更好地理解数据&#xff1a;通过可视化数据&#xff0c;人们可以更好地…

告别腾讯企业邮箱:探寻多种可替代方案

腾讯企业邮箱凭借其直观的界面、qq和微信带来的大量基础用户以及作为常规腾讯企业邮箱帐户附加的各种免费生产力工具&#xff0c;在企业邮箱市场占据主导地位。但是&#xff0c;人们对腾讯如何使用您的电子邮件存在严重担忧&#xff0c;而且并不是每个人都喜欢腾讯企业邮箱界面…

ngrok实现内网穿透,vue项目invalid host header报错

目的&#xff1a;使自己的本地的vue项目可以在外网上访问。 本地访问&#xff1a;http://localhost:8080/ 外网访问&#xff1a;通过ngrok生成一个链接&#xff0c;这个链接在其他网络环境下都可以访问。 windows下安装 1.注册并下载ngrok&#xff0c;注册的时候需要验证码&am…

动手学习卷积神经网络(CNN)(一)---卷积运算

卷积神经网络可以直接从原始数据中学习其特征表示并完成最终任务&#xff0c;可以说卷积网络是“端”到“端”的思想&#xff0c;在整个学习流程中并进行认为的子问题划分&#xff0c;而是交给深度学习模型直接学得从原始输入到期望输出得映射。 卷积神经网络是包含卷积层&…

一个BLIP2加两个ChatGPT就能造一个机器人?KAUST提出具身智能框架LLM-Brain

最近&#xff0c;来自阿卜杜拉国王科技大学&#xff08;KAUST&#xff09;的研究团队开发了一种基于现有LLMs的机器人交互框架LLM-Brain&#xff0c;LLM-Brain可以直接将LLM作为机器人的大脑&#xff0c;并以此来构建一个以自我为中心的记忆和控制框架。 论文链接&#xff1a; …

【笔试强训选择题】Day18.习题(错题)解析

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;笔试强训选择题 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01;&#xff01; 文章目录…

红队工具合集

一个 Red Team 攻击的生命周期&#xff0c;整个生命周期包括&#xff1a; 信息收集、攻击尝试获得权限、持久性控制、权限提升、网络信息收集、横向移动、数据分析&#xff08;在这个基础上再做持久化控制&#xff09;、在所有攻击结束之后清理并退出战场。 相资 信息搜集 http…

自信裸辞:一晃 ,失业都3个月了.....

最近&#xff0c;找了很多软测行业的朋友聊天、吃饭 &#xff0c;了解了一些很意外的现状 。 我一直觉得他们技术非常不错&#xff0c;也走的测开/管理的路径&#xff1b;二三月份裸辞的&#xff0c;然后一直在找工作&#xff0c;现在还没找到工作 。 经过我的分析&#xff0…