IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 目标跟踪-边缘跟踪 -> 正文阅读

[人工智能]目标跟踪-边缘跟踪

边缘跟踪算法实现过程

网上大部分关于边缘跟踪的算法不是目标跟踪领域,而是串接目标的边缘,和区域生长法作用一样。极少有文献是关于目标跟踪领域的边缘跟踪算法。

边缘跟踪算法主要包括4个步骤:

  1. 帧间波门内差分;
  2. 波门内阈值分割;
  3. 波门内去噪声;
  4. 计算边缘点(中心)

前面三步和质心跟踪算法一样,第4步如果是计算单个边缘点,就是单边缘跟踪,如果是计算边缘点的中心,就是双边缘中心跟踪。这里以双边缘中心跟踪为例。

帧间波门内差分

相邻帧之间在波门内进行差分操作。为了仅体现相邻帧之间的变化量,这里我做了绝对值差分操作。即
D i f f x , y = ∣ f x , y i + 1 ? f x , y i ∣ Diff_{x,y} = |f^{i+1}_{x,y} - f^i_{x,y}| Diffx,y?=fx,yi+1??fx,yi?
f i + 1 f^{i+1} fi+1和f^i是相邻帧的波门框定图像。x, y表示具体坐标。通过绝对差分可以表征帧间目标的变化量。具体函数如下:

cv::absdiff(gray_image(_roi), this->gray_image(_roi), diff);

波门内阈值分割

在得到差分图像以后,有可能差分图像本身的对比度较低。我们需要对差分图像进行二值化来进一步体现目标的变化量。一般的图像二值化可以固定一个阈值比如127u,但是差分图像需要自适应地选择阈值来进行分割。此处选择最大类间方差算法来选择分割阈值。具体思想可以参见:https://blog.csdn.net/zhu_hongji/article/details/80967776

int EdgeTracker::getThresholdValue(cv::Mat& image);

选择了最优阈值之后,就对图像进行二值分割。

void EdgeTracker::segmentByThreshold(cv::Mat& src, cv::Mat& dst, int threshold);

波门内去噪声

去噪声这一步是可选的,在实现里我采用腐蚀+膨胀的方法(被注释掉了),腐蚀是为了去除白噪点,膨胀是为了突出目标的变化量。结构元素3x3。

计算边缘的中心

计算边缘点的中心是根据阈值分割后的图来的,这一步思想非常简单,就是找目标的上下左右边界。形式化表述如下:
y u p p e r = max ? { y ? ∣ ? y < y ? , 0 < x < W , I ( x , y ) = 0 } y l o w e r = min ? { y ? ∣ ? y > y ? , 0 < x < W , I ( x , y ) = 0 } x l e f t = max ? { x ? ∣ ? x < x ? , 0 < y < H , I ( x , y ) = 0 } x r i g h t = min ? { x ? ∣ ? x > x ? , 0 < y < H , I ( x , y ) = 0 } y_{upper} = \max \{y^* | \forall y < y^*, 0 < x < W, I(x, y) = 0 \} \\ y_{lower} = \min \{y^* | \forall y > y^*, 0 < x < W, I(x, y) = 0 \} \\ x_{left} = \max \{x^* | \forall x < x^*, 0 < y < H, I(x, y) = 0 \} \\ x_{right} = \min \{x^* | \forall x > x^*, 0 < y < H, I(x, y) = 0 \} \\ yupper?=max{y??y<y?,0<x<W,I(x,y)=0}ylower?=min{y??y>y?,0<x<W,I(x,y)=0}xleft?=max{x??x<x?,0<y<H,I(x,y)=0}xright?=min{x??x>x?,0<y<H,I(x,y)=0}
其中, y u p p e r y_{upper} yupper?, y l o w e r y_{lower} ylower?分别表示目标的上下边界的纵坐标, x l e f t x_{left} xleft?, x r i g h t x_{right} xright?分别表示目标的左右边界的横坐标, W W W H H H分别为图像的宽度和高度。

那么可以得到4个边缘点的坐标为:
p u p p e r = ( x l e f t + x r i g h t 2 , y u p p e r ) p l o w e r = ( x l e f t + x r i g h t 2 , y l o w e r ) p l e f t = ( x l e f t , y u p p e r + y l o w e r 2 ) p r i g h t = ( x r i g h t , y u p p e r + y l o w e r 2 ) p_{upper} = (\frac{x_{left} + x_{right}}{2}, y_{upper}) \\ p_{lower} = (\frac{x_{left} + x_{right}}{2}, y_{lower}) \\ p_{left} = (x_{left}, \frac{y_{upper} + y_{lower}}{2}) \\ p_{right} = (x_{right}, \frac{y_{upper} + y_{lower}}{2}) pupper?=(2xleft?+xright??,yupper?)plower?=(2xleft?+xright??,ylower?)pleft?=(xleft?,2yupper?+ylower??)pright?=(xright?,2yupper?+ylower??)

如果只利用其中一个边缘点,那么可以导出单边缘跟踪算法,这里介绍双边缘跟踪算法,实际上就是计算这4个点的中心坐标, 也就是
p c e n t e r = ( x l e f t + x r i g h t 2 , y u p p e r + y l o w e r 2 ) p_{center} = (\frac{x_{left} + x_{right}}{2}, \frac{y_{upper} + y_{lower}}{2}) pcenter?=(2xleft?+xright??,2yupper?+ylower??)

p c e n t e r p_{center} pcenter?的偏移可以导出目标在不同帧的移动路径,并由此确定当前帧目标的波门。

头文件如下:

class EdgeTracker : CustomTracker
{
public:
    EdgeTracker(bool debug = false);
    ~EdgeTracker();
    void init(cv::Mat& image, const cv::Rect_<int> &roi);
    cv::Rect_<int> update(cv::Mat& image);
    cv::Mat getDiff(cv::Mat& gray_image);
    int getThresholdValue(cv::Mat& image);
    void segmentByThreshold(cv::Mat& src, cv::Mat& dst, int threshold);
    vector<cv::Point_<int>> findEdgePoints(cv::Mat& seg_map);

protected:
    cv::Rect_<float> _roi;
    cv::Mat image;
    cv::Mat gray_image;
    bool DEBUG = false;
    vector<cv::Point_<int>> edge_points; // centerp_upper, centerp_lower, centerp_left, centerp_right
    int ite_num;
    bool first_ite;
};

核心代码如下:

vector<cv::Point_<int>> EdgeTracker::findEdgePoints(cv::Mat& seg_map)
{
    int x0, y0, x1, y1;
    x0 = 0;
    y0 = 0;
    x1 = _roi.width-1;
    y1 = _roi.height-1;
    int width = seg_map.cols;
    int height = seg_map.rows;
    bool flag1 = false, flag2 = false;
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            uint8_t pix0 = seg_map.ptr<uint8_t>(i)[j];
            uint8_t pix1 = seg_map.ptr<uint8_t>(height-i-1)[j];
            if (pix0 == 255 && !flag1)
            {
                y0 = i;
                flag1 = true;
            }
            if (pix1 == 255 && !flag2)
            {
                y1 = height-i-1;
                flag2 = true;
            }
            if (flag1 && flag2) 
            {
                flag1 = flag2 = false;
                goto P1;
            }
        }
    }
    P1: for (int i = 0; i < width; i++)
    {
        for (int j = 0; j < height; j++)
        {
            uint8_t pix0 = seg_map.ptr<uint8_t>(j)[i];
            uint8_t pix1 = seg_map.ptr<uint8_t>(j)[width-i-1];
            if (pix0 == 255)
            {
                x0 = i;
                flag1 = true;
            }
            if (pix1 == 255)
            {
                x1 = width-i-1;
                flag2 = true;
            }
            if (flag1 && flag2) goto P2;
        }
    }
    P2: // 计算4个边缘点的坐标
    vector<cv::Point_<int>> points;
    cv::Point_<int> upper, lower, left, right;
    upper.x = (x0 + x1) / 2;
    upper.y = y0;
    lower.x = (x0 + x1) / 2;
    lower.y = y1;
    left.x = x0;
    left.y = (y0 + y1) / 2;
    right.x = x1;
    right.y = (y0 + y1) / 2;
    points.push_back(upper);
    points.push_back(lower);
    points.push_back(left);
    points.push_back(right);
    return points;
}
  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-12-24 18:28:52  更:2021-12-24 18:31:38 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 23:24:06-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码