• seam carving---学习笔记


    1. 是一种算法,一种内容感知的图像缩放算法,一般用于图像的裁减。
    2. 提出背景:
      1. 直接缩放的问题:如果宽高比例不一致,会导致内容发生形变“失真”
      2. seam carving:尽可能保持图像中“重要区域”的比例。
    3. 可以只理解图像宽度缩小算法,对于图像高度缩小,只需对图像转置处理
    4. 算法的基本思想:缩放的实质删去若干条纵向的像素“路径”,而直接缩放删除的路径都是竖直的长条,相当于验证图像竖直方向做了均匀的降采样。但如果删除的路径是最不重要的,则可以实现基于图像内容的缩放。
    5. 实现概述:
      1.  能量:梯度信息,用像素在水平和竖直方向上的一阶梯度值的之和来表示该像素点的能量,那么一条缝隙的能量就是该缝隙上所有像素点能量之和。
      2. 需要做的就是每次找到像素能量最小的一条缝隙,然后删去它。
      3. 找能量线,然后将线上的像素点全部删能量图除,从而实现缩小。迭代,每次移除后需要重新计算能量图,即梯度图需要重新计算,才可进行下一次移除。
    6. 算法流程:
      1. 计算图像能量图:
        1. 能量图一般是图像像素的梯度模值,为了简化计算可先转换成灰度图像,然后直接用x、y方向上的差分取绝对值,然后相加,这一步相当于边缘检测
        2. 能量图的计算:可以利用 OpenCV 中的 cv::Sobel 计算能量图
      2. 寻找最小能量线:
        1. 最小能量线是要被移除的,首先需要以图像第一行或最后一行为开始行进行迭代
        2. 找出最后一行需要被移除的像素点后,设其坐标为P(x,y),然后往上一行寻找,寻找的点为P点的在y-1行中的三个相邻像素点中的能量最小值像素。也就是寻找的坐标为(x-1,y-1)、(x,y-1)、(x+1,y-1);
        3. 使用动态规划查找最优 seam,以竖直 seam 为例:

          1. 可以看成图论里的最短路径问题,把每个像素点看成一个节点,像素 (i, j) 连通的边只有上一行的左、中、右和下一行的左、中、右像素,那么我们要找的就是从图像第一行像素出发到图像最后一行像素的最短路。

          2. 可以用经典的最短路算法来求解,然而这里可以用动态规划进行更高效的求解:设图像宽、高分别为 W,H,记 M[i][j] 为到 (i, j) 像素点的最优 seam 的像素能量和,那么我们只要找到最后一行里能量最小的像素,即 min(M[H-1][j]),然后回溯即可以找到最优 seam。

          3. 放大:插入 k 条新 seam,那么先一次性找到 k 条最优 seam,然后按反向顺序逐一取左右 seam 平均插入到图像中即可。

      3. 移除最小能量线,让图片的宽度缩小一个像素:
        1. 移除最小能量线,同时所有位于最小能量线右边的像素点左移一个单位,从而实现图像缩小宽度缩小一个单位。
        2. 移除时为了让图像看起来自然,需要在移除缝线的地方进行平均,假设移除坐标为P(x,y),那么移除后P(x-1,y)的像素值为P(x-1,y)与P(x,y)的像素值的平均。P(x+1,y)的像素值为P(x-1,y)与P(x,y)的像素值的平均,然后才能把P(x+1,y)移动到P(x,y)的位置。
        3. 对于图像的放大算法原理一样,先找到最小能量线,设能量线上点的坐标为P(x,y),则在P(x,y)、P(x+1,y)中心位置插入新的像素,像素值为P(x,y)与P(x+1,y)的平均。
    7. 应用:可以通过修改能量图来实现图像中目标的保护和去除(即抠图),增加能量图中相关像素的能量值则可以起到保护作用,降低能量值则可以起到删除作用。
  • 相关阅读:
    Spring Boot Admin 介绍及使用
    【Flink】一文解析Flink如何实现状态管理和容错机制
    AQS简介
    Jenkins 配置 WebHooks
    【Cherno的C++视频】Smart pointers in C++
    Effective Modern C++[实践]->优选delete关键字删除函数,而非private未定义函数
    【c#版本Openfeign】Net8 自带OpenFeign实现远程接口调用
    【Linux】环境变量
    vue中的常用指令
    【编程语言发展史】SQL的发展历史
  • 原文地址:https://blog.csdn.net/weixin_45647721/article/details/126813315