关于大图片的小目标的检测方法:将图片拆成四个分开去放到目标去训练

关于大图片的小目标的检测方法:将图片拆成四个分开去放到目标去训练

1 概述

​ 在yolov5 的网络模型中大抵输入的图片为640*640,如果是3000 * 2000的图片去检测大概100像素左右的目标,会比较容易漏掉,这大概也和我的数据值过于少有关。所以我这种也算是一种数据增强的方式!

方法: 暴力搜索 和 带方向的暴力搜索

2 环境

  • ubuntu 18.04
  • pycharm2020.01
  • yolov5 的要求环境

3 暴力搜索

3.1思路:

在这里插入图片描述

参考上图:

  1. 在给定的图片(width,height),以他们的中心点作为 起始点 centerpoint = (width/2 , height/2)
  2. 读取图片对应的 label 的文件,获得每个gtbox 的中心点,将其放入集合 - pointsList
  3. 设定阈值threshold,通过该阈值建立了矩形面积,如果gtbox 的点落在该矩形中 则需要重新挑选该方向的中心点–》第四点,否则该centerpoint 就是该方向的最合适的
  4. 如何挑选呢?在图像搜索起始点 search Start Point 到 search End Point 依次遍历的点pixel 作为其中心点
  5. 则新的矩形也通过threshold 建立起来,再次检测所有gtbox 的中心点是否落在矩形中,如果没有,则将其添加到我们的侯选集合,否则跳过改循环继续寻找。
  6. 在候选集合中点寻找最靠近图像中心的点,找到该点并返回
  7. 如果没有找到一个合适的候选点 则返回-1
3.2 代码如下:
def searchCenter(pointlist, neg_limit, pos_limit, centerPoint, dir, limit=10,debug=False):
    '''
    单方向 从负极限到正极限 搜索 中心点最适合点
    Args:
        pointlist: 搜索须满足的点集合
        neg_limit: 负极限
        pos_limit: 正极限
        centerPoint: 中心点的值
        dir: 方向 x :0  y:1
        limit: 中心点的允许值

    Returns: -1 没有找到合适的点
                or
                一个最合适点

    '''
    # 后选集
    Candidate_list = []
    num = len(pointlist)
    if debug:
        print(f"搜索范围 {neg_limit} : {pos_limit}")

    for x_pixel in range(neg_limit, pos_limit):
        temp = 0
        neg_center_limit = x_pixel - limit
        pos_center_limit = x_pixel + limit

        stra = 'p: '
        for point in pointlist:
            stra += (' ' + str(point[dir]))
            if point[dir] < neg_center_limit or point[dir] > pos_center_limit:
                temp += 1
        if temp == num:
            # Shuo说明该pixel 符合要求
            Candidate_list.append(x_pixel)
            if debug:
                print('*' * 50)
                print(stra)
                print(f'后选集添加:{x_pixel},判断负界限:{neg_center_limit},判断正界限:{pos_center_limit},temp:{temp},num:{num} \n')
                print('*' * 50)


    if len(Candidate_list) != 0:
        # 所有的候选集 到中心点最近的一条线
        Candinate_array = np.array(Candidate_list)
        center = np.array([centerPoint])
        tempArray = abs(Candinate_array - center)
        # qiu丘处最小值的索引
        minindex = np.argmin(tempArray, axis=0)

        if debug:
            print(f'所有的后选集:{Candinate_array}\n')
            print(f'处理后的后选集:{tempArray}\n')
            print(f'所有的后选集的最小值:{Candinate_array[minindex]}\n')
        # fan返回最小值的索引对应的数
        return Candinate_array[minindex]
    else:
        return -1

def demo_Brute_force_search(n=4 , width=100, height=100,debug=True):
    # n = 4  # 生成几个点
    # 随即生成n dian
    randomPoingList = []
    for i in range(n):
        x, y = random.randint(0, width), random.randint(0, height)
        randomPoingList.append((x, y))

    if debug:
        print(f'随即生成点为\n')
        for i in range(len(randomPoingList)):
            print(f'point{i}: {randomPoingList[i]} \n')

    # 中心点 的坐标值 一般是图像w/2 h/2
    cx, cy = width //2 , height // 2
    # 限定距离阈值
    limit = 10
    l_center_limit = cx - limit
    r_center_limit = cx + limit
    u_center_limit = cy - limit
    d_center_limit = cy + limit

    l_limit = width // 3  # 左界限
    r_limit = width // 3 * 2  # 右界限
    u_limit = height // 3  # 上界限
    d_limit = height // 3 * 2  # 下界限

    if debug:
        print(f'中心点的值: {cx}, {cy}\n'
              f'允许阀值 {limit}\n')
        print(f"水平允许范围 {l_center_limit} : {r_center_limit}\n ")
        print(f"水平允许范围 {u_center_limit} : {d_center_limit}\n ")
        print(f'搜索水平界限 {l_limit}:{r_limit} \n')
        print(f'搜索垂直界限 {u_limit}:{d_limit} \n')

    # 检测所有点是否符合需求
    fitNums_x = 0
    fitNums_y = 0
    num = len(randomPoingList)
    for point in randomPoingList:
        if point[0] < l_center_limit or point[0] > r_center_limit:
            fitNums_x += 1
        if point[1] < u_center_limit or point[1] > d_center_limit:
            fitNums_y += 1
    if debug:
        print(f'fitNums_x:{fitNums_x}')
        print(f'fitNums_y:{fitNums_y}')
    if fitNums_x != num:
        if debug:
            print(f'x 点不满足,当前点数: {fitNums_x} 需求数目: {num} 开始搜索模式:\n')
        # 说明有点不满足 开始搜索模式
        # 搜索模式: 重新调整中心点 在范围内不断重新调整中心点位置 -》 最合适的点 x中心点
        x_pixel_centerPoint = searchCenter(randomPoingList, l_limit, r_limit, cx, 0, 10,debug)
        if x_pixel_centerPoint == -1:
            assert ValueError("can't find compitable point")
    else:
        x_pixel_centerPoint = cx
    if fitNums_y != num:
        if debug:
            print(f'y 点不满足,当前点数: {fitNums_y} 需求数目: {num} 开始搜索模式:\n')
        # 说明有点不满足 开始搜索模式
        # 搜索模式: 重新调整中心点 在范围内不断重新调整中心点位置 -》 最合适的点 x中心点
        y_pixel_centerPoint = searchCenter(randomPoingList, u_limit, d_limit, cy, 1, 10, debug)
        if y_pixel_centerPoint == -1:
            assert ValueError("can't find compitable point")
    else:
        y_pixel_centerPoint = cy

    # 至此得到 最合适的中心点位置
    return x_pixel_centerPoint, y_pixel_centerPoint

if __name__ == '__main__':
    demox,demoy = demo_Brute_force_search(n=200,width=3000,height=2000,debug=False)
    print(f'最合适的xy点:{demox},{demoy}  j= {j}')
    

3.3 总结

3.3.1 上述的代码中:

​ n = 200 表示随即生成的 label 点

​ debug=False 是否是调试模式,调试模式下会打印中间 的值

​ 搜索范围我限定在 图像的 1/3 到 2/3 这里

l_limit = width // 3  # 左界限
r_limit = width // 3 * 2  # 右界限
u_limit = height // 3  # 上界限
d_limit = height // 3 * 2  # 下界限
3.3.2 实验总结:

​ 我大概实验了100次,随即的点数目在 200-1000 逐步往上涨,閾值=10,搜索范围在图像的 1/3 到 2/3 大概在 300 左右会出现找不到合适的中心值

最合适的xy点:1493,-1  j= 325
最合适的xy点:1575,-1  j= 355
最合适的xy点:1500,-1  j= 316
最合适的xy点:1509,-1  j= 357
最合适的xy点:1443,-1  j= 334
最合适的xy点:1518,-1  j= 330
最合适的xy点:1500,-1  j= 336
最合适的xy点:1525,-1  j= 320
最合适的xy点:1543,-1  j= 278
最合适的xy点:1537,-1  j= 288
最合适的xy点:1509,-1  j= 335
最合适的xy点:1523,-1  j= 388
最合适的xy点:1504,-1  j= 358
最合适的xy点:1500,-1  j= 317
最合适的xy点:1546,-1  j= 342
最合适的xy点:1498,-1  j= 282
最合适的xy点:1497,-1  j= 300
最合适的xy点:1565,-1  j= 305
最合适的xy点:1500,-1  j= 329
最合适的xy点:1490,-1  j= 300
最合适的xy点:1649,-1  j= 340
最合适的xy点:1526,-1  j= 346
最合适的xy点:1558,-1  j= 311
最合适的xy点:1500,-1  j= 345
最合适的xy点:1468,-1  j= 325
最合适的xy点:1444,-1  j= 297
最合适的xy点:1524,-1  j= 359
最合适的xy点:1487,-1  j= 271
最合适的xy点:1511,-1  j= 359
最合适的xy点:1503,-1  j= 293
最合适的xy点:1504,-1  j= 312
最合适的xy点:1571,-1  j= 310
最合适的xy点:1437,-1  j= 317
最合适的xy点:1526,-1  j= 338
最合适的xy点:1434,-1  j= 337
最合适的xy点:1520,-1  j= 334
最合适的xy点:1494,-1  j= 299
最合适的xy点:1534,-1  j= 333
最合适的xy点:1572,-1  j= 352
最合适的xy点:1496,-1  j= 290
最合适的xy点:1523,-1  j= 353
最合适的xy点:1419,-1  j= 305
最合适的xy点:1514,-1  j= 317
最合适的xy点:1496,-1  j= 340
最合适的xy点:1500,-1  j= 320
最合适的xy点:1495,-1  j= 346
最合适的xy点:1461,-1  j= 374
最合适的xy点:1441,-1  j= 307
最合适的xy点:1488,-1  j= 309
最合适的xy点:1523,-1  j= 308
最合适的xy点:1430,-1  j= 327
最合适的xy点:1480,-1  j= 294
最合适的xy点:1504,-1  j= 277
最合适的xy点:1500,-1  j= 315
最合适的xy点:1512,-1  j= 313
最合适的xy点:1530,-1  j= 375
最合适的xy点:1513,-1  j= 304
最合适的xy点:1545,-1  j= 347
最合适的xy点:1492,-1  j= 342
最合适的xy点:1481,-1  j= 363
最合适的xy点:1520,-1  j= 353
最合适的xy点:1472,-1  j= 346
最合适的xy点:1496,-1  j= 378
最合适的xy点:1447,-1  j= 306
最合适的xy点:1341,-1  j= 362
最合适的xy点:1532,-1  j= 318
最合适的xy点:1500,-1  j= 307
最合适的xy点:1469,-1  j= 306
最合适的xy点:1501,-1  j= 388
最合适的xy点:1497,-1  j= 281
最合适的xy点:1498,-1  j= 355
最合适的xy点:1471,-1  j= 308
最合适的xy点:1542,-1  j= 315
最合适的xy点:1554,-1  j= 300
最合适的xy点:1485,-1  j= 354
最合适的xy点:1441,-1  j= 335
最合适的xy点:1506,-1  j= 313
最合适的xy点:1493,-1  j= 319
最合适的xy点:1475,-1  j= 337
最合适的xy点:1551,-1  j= 307
最合适的xy点:1579,-1  j= 362
最合适的xy点:1475,-1  j= 320
最合适的xy点:1426,-1  j= 364
最合适的xy点:1507,-1  j= 313
最合适的xy点:1500,-1  j= 317
最合适的xy点:1508,-1  j= 335
最合适的xy点:1494,-1  j= 314
最合适的xy点:1585,-1  j= 274
最合适的xy点:1464,-1  j= 328
最合适的xy点:1508,-1  j= 249
最合适的xy点:1508,-1  j= 347
最合适的xy点:1500,-1  j= 331
最合适的xy点:1490,-1  j= 339
最合适的xy点:1500,-1  j= 345
最合适的xy点:1532,-1  j= 332
最合适的xy点:1513,-1  j= 328
最合适的xy点:1500,-1  j= 376
最合适的xy点:1588,-1  j= 306
最合适的xy点:1536,-1  j= 329
最合适的xy点:1451,-1  j= 361

Process finished with exit code 0		
  • 2
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值