0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

我们如何定义ROI?

新机器视觉 来源:小白学视觉 作者:努比 2022-06-09 11:12 次阅读

OpenCV是一个巨大的开源库,广泛用于计算机视觉人工智能和图像处理领域。它在现实世界中的典型应用是人脸识别,物体检测,人类活动识别,物体跟踪等。

现在,假设我们只需要从整个输入帧中检测到一个对象。因此,代替处理整个框架,如果可以在框架中定义一个子区域并将其视为要应用处理的新框架,该怎么办。我们要完成一下三个步骤:

定义兴趣区

在ROI中检测轮廓

阈值检测轮廓轮廓线

什么是ROI

简而言之,我们感兴趣的对象所在的帧内的子区域称为感兴趣区域(ROI)。

我们如何定义ROI?

在输入帧中定义ROI的过程称为ROI分割。

在“ ROI细分”中,(此处)我们选择框架中的特定区域,并以矩形方法提供其尺寸,以便它将在框架上绘制矩形的ROI。

1934a0e2-e731-11ec-ba43-dac502259ad0.png

(输出)蓝色矩形覆盖的区域是我们的投资回报率

现在,如果您也想绑定感兴趣的对象,那么我们可以通过在ROI中找到轮廓来实现。

什么是轮廓?

轮廓线是表示或说是限制对象形状的轮廓。

如何在框架中找到轮廓?

对我而言,在将ROI框架设为阈值后,找到轮廓效果最佳。因此,要找到轮廓,手上的问题是-

什么是阈值?

阈值不过是图像分割的一种简单形式。这是将灰度或rgb图像转换为二进制图像的过程。例如

198779c0-e731-11ec-ba43-dac502259ad0.png

(这是RGB帧)

19acae20-e731-11ec-ba43-dac502259ad0.png

(这是二进制阈值帧)

因此,在对rgb帧进行阈值处理后,程序很容易找到轮廓,因为由于ROI中感兴趣对象的颜色将是黑色(在简单的二进制脱粒中)或白色(在如上所述的反向二进制脱粒中),因此分割(将背景与前景即我们的对象分开)将很容易完成。

在对框架进行阈值处理并检测到轮廓之后,我们应用凸包技术对围绕对象点的紧密拟合凸边界进行设置。实施此步骤后,框架应如下所示-

19ce95f8-e731-11ec-ba43-dac502259ad0.png

我们可以做的另一件事是,我们可以遮盖ROI以仅显示被检测到的轮廓本身覆盖的对象。再次-

什么是图像MASK?

图像MASK是隐藏图像的某些部分并显示某些部分的过程。这是图像编辑的非破坏性过程。在大多数情况下,它使您可以在以后根据需要调整和调整遮罩。通常,它是一种有效且更具创意的图像处理方式。

因此,基本上在这里我们将掩盖ROI的背景。为此,首先我们将修复ROI的背景。然后,在固定背景之后,我们将从框架中减去背景,并用wewant背景(这里是一个简单的黑色框架)替换它。

实施上述技术,我们应该得到如下输出:

19f5abd4-e731-11ec-ba43-dac502259ad0.png

(背景被遮罩以仅捕获对象)

这是所说明技术的理想实现的完整代码。


import cv2import numpy as npimport copyimport math
x=0.5  # start point/total widthy=0.8  # start point/total widththreshold = 60  # BINARY thresholdblurValue = 7  # GaussianBlur parameterbgSubThreshold = 50learningRate = 0
# variablesisBgCaptured = 0   # whether the background captured
def removeBG(frame): #Subtracting the background    fgmask = bgModel.apply(frame,learningRate=learningRate)
    kernel = np.ones((3, 3), np.uint8)    fgmask = cv2.erode(fgmask, kernel, iterations=1)    res = cv2.bitwise_and(frame, frame, mask=fgmask)    return res
# Cameracamera = cv2.VideoCapture(0)camera.set(10,200)


while camera.isOpened():    ret, frame = camera.read()    frame = cv2.bilateralFilter(frame, 5, 50, 100)  # smoothening filter    frame = cv2.flip(frame, 1)  # flip the frame horizontally    cv2.rectangle(frame, (int(x * frame.shape[1]), 0),                 (frame.shape[1], int(y * frame.shape[0])), (255, 0, 0), 2) #drawing ROI    cv2.imshow('original', frame)
    #  Main operation    if isBgCaptured == 1:  # this part wont run until background captured        img = removeBG(frame)        img = img[0:int(y * frame.shape[0]),                    int(x * frame.shape[1]):frame.shape[1]]  # clip the ROI        cv2.imshow('mask', img)
        # convert the image into binary image        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)        blur = cv2.GaussianBlur(gray, (blurValue, blurValue), 0)        cv2.imshow('blur', blur)        ret, thresh = cv2.threshold(blur, threshold, 255, cv2.THRESH_BINARY) #thresholding the frame        cv2.imshow('ori', thresh)

        # get the coutours        thresh1 = copy.deepcopy(thresh)        contours, hierarchy = cv2.findContours(thresh1, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) #detecting contours        length = len(contours)        maxArea = -1        if length > 0:            for i in range(length):  # find the biggest contour (according to area)                temp = contours[i]                area = cv2.contourArea(temp)                if area > maxArea:                    maxArea = area                    ci = i
            res = contours[ci]            hull = cv2.convexHull(res) #applying convex hull technique            drawing = np.zeros(img.shape, np.uint8)            cv2.drawContours(drawing, [res], 0, (0, 255, 0), 2) #drawing contours             cv2.drawContours(drawing, [hull], 0, (0, 0, 255), 3) #drawing convex hull            cv2.imshow('output', drawing)
    # Keyboard OP    k = cv2.waitKey(10)    if k == 27:          camera.release()        cv2.destroyAllWindows()        break    elif k == ord('b'):  # press 'b' to capture the background        bgModel = cv2.createBackgroundSubtractorMOG2(0, bgSubThreshold)        isBgCaptured = 1        print( 'Background Captured')    elif k == ord('r'):  # press 'r' to reset the background        bgModel = None        isBgCaptured = 0print('ResetBackGround')

审核编辑 :李倩


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 人脸识别
    +关注

    关注

    76

    文章

    4012

    浏览量

    81891
  • OpenCV
    +关注

    关注

    31

    文章

    635

    浏览量

    41345

原文标题:基于OpenCV的区域分割、轮廓检测和阈值处理

文章出处:【微信号:vision263com,微信公众号:新机器视觉】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    《DNK210使用指南 -CanMV版 V1.0》第三十八章 image码识别实验

    find_barcodes()方法,用于识别图像中的条形码,find_barcodes()方法如下所示:image.find_barcodes(roi)find_barcodes()方法用于识别图像中的条形码
    发表于 11-13 09:35

    抖动定义和测量

    引言:时钟抖动(jitter)是现代通信和数字系统中至关重要的性能指标之一,对数据传输速率和系统同步起着关键作用。本文将深入探讨时钟抖动的定义、不同类型,详细介绍各种抖动类型的测试方法,并分析时钟
    的头像 发表于 10-21 16:15 408次阅读
    抖动<b class='flag-5'>定义</b>和测量

    电位的定义与规定

    参考点的电压。这个定义揭示了电位的本质:它是一个相对量,用于描述电路中某点与参考点之间的电压差。为了便于理解和计算,我们通常将电路中的某一点(如电源的负极)作为参考点,并规定其电位为零。这个参考点也被称为“接地
    的头像 发表于 09-24 17:50 1954次阅读

    SPI总线的定义和特点

    SPI总线(Serial Peripheral Interface),全称为串行外围设备接口,是由Motorola公司提出并定义的一种同步、串行、高速的通信总线。SPI总线以其独特的优势在电子通信
    的头像 发表于 09-03 14:05 825次阅读

    如何使用云服务器刷写自定义固件?

    我们正在尝试在没有以前刷新固件的情况下刷新我们的自定义固件。所以里面有原装AT固件。 当模块连接到 WiFi 和互联网时,在 AT CIUPDATE 之后一切正常。但它正在下载/更新您的原始
    发表于 07-15 08:23

    GPT的定义和演进历程

    GPT,全称Generative Pretrained Transformer,是OpenAI公司在自然语言处理(NLP)领域的一项重大创新。这一模型不仅推动了AI技术的边界,还深刻影响了我们与机器交互的方式。本文将从GPT的定义、来源、演进历程以及其在各个领域的应用和影
    的头像 发表于 07-10 10:41 1062次阅读

    为什么我们需要软件定义的工厂?

    软件定义的工厂使制造商能够快速响应市场趋势并减少计划外停机时间,从而提高工厂的生产力。 在工业4.0时代保持竞争力意味着制造商必须足够灵活,以设计选择,并能够改变生产工艺,以满足不同的客户偏好或独特
    的头像 发表于 07-03 14:34 6661次阅读

    SIM卡座的接口定义

    SIM卡座连接器的接口定义是移动通信设备中不可或缺的一部分,确保了SIM卡与设备之间的稳定通信和数据传输。在本文中,连欣科技将详细探讨一下SIM卡座的接口定义,包括其结构、引脚功能、以及接口标准,为
    的头像 发表于 06-17 17:47 4054次阅读
    SIM卡座的接口<b class='flag-5'>定义</b>

    高速pcb的定义是什么

    高速pcb的定义是什么 高速PCB(Printed Circuit Board,印刷电路板)是指在高速信号传输、高频应用和高密度布局等方面具有特定设计要求的电路板。随着电子技术的飞速发展,高速PCB
    的头像 发表于 06-10 17:31 1577次阅读

    TSMaster 自定义 LIN 调度表编程指导

    LIN(LocalInterconnectNetwork)协议调度表是用于LIN总线通信中的消息调度的一种机制,我们收到越来越多来自不同用户希望能够通过接口实现自定义LIN调度表的需求。所以在
    的头像 发表于 05-11 08:21 672次阅读
    TSMaster 自<b class='flag-5'>定义</b> LIN 调度表编程指导

    PHP用户定义函数详细讲解

    描述 在所有编程和脚本语言中,函数是可以在程序中重复使用的语句块。在 PHP 中,函数的概念与另一种语言(如“C”)中的概念相同。标准 PHP 发行版中有 1,000 多个内置函数。除此之外,我们
    的头像 发表于 03-20 14:27 400次阅读

    汽车电器各部分线束接口定义

      一。整车保险及搭铁点设置说明二。驾驶室与底盘线对接定义三。驾驶室与前围线对接定义四。驾驶室与前灯线对接定义
    发表于 03-07 14:55 1287次阅读
    汽车电器各部分线束接口<b class='flag-5'>定义</b>

    IGBT和MOSFET在对饱和区的定义差别

    它们对饱和区的定义有一些差别。 首先,让我们从基本原理开始理解饱和区。在晶体管中,饱和区是电流最大的区域,通常被用来实现开关操作。晶体管在饱和区工作时,处于最低的电压状态,导通电流较大。然而,饱和区的定义在IGBT和MOSFET
    的头像 发表于 02-18 14:35 2179次阅读

    物联网中继器的定义和作用

    有限的问题。在本文中,我们将详细讨论物联网中继器的定义、原理、作用以及它为物联网发展带来的影响。 首先,我们来了解一下物联网中继器的定义。物联网中继器是一种用于扩展和增强物联网网络覆盖
    的头像 发表于 02-01 10:02 1587次阅读

    EMC和MEA的定义和区别

     EMC(Electromagnetic Compatibility,电磁兼容性)和MEA(Medical Electrical Equipment,医疗电气设备)是电子和电气领域中两个不同的概念,它们有着不同的定义和应用。
    发表于 01-10 11:27 1196次阅读
    EMC和MEA的<b class='flag-5'>定义</b>和区别