使用Python、OpenCV进行图像接缝雕刻

这篇博客将介绍基于图像内容感知调整的接缝雕刻算法。Avidan和Shimar证明了接缝雕刻不仅可以用于缩小图像尺寸,还可以用于增大图像尺寸;然而,scikit图像实现目前只支持下采样。

接缝雕刻算法也有它的局限性,对于接缝雕刻,该缺陷表现为图像的重要语义信息被部分破坏或完全切断,视觉效果不佳。

1. 效果图

原始图 VS 水平接缝效果图
如下图,可以看到已经从图像中删除了垂直接缝,从而减小了图像宽度。
也可以通过移除水平接缝来降低图像高度:
在这里插入图片描述
原始图 VS 垂直接缝效果图
如下图,可以看到已经从图像中删除了水平接缝,从而减小了图像高度。
在这里插入图片描述根据原始图像计算能量图(即梯度图)
在这里插入图片描述

2. 原理

接缝雕刻算法是什么?

接缝雕刻算法通过移除/添加低能量的接缝来调整图像的大小(包括上采样和下采样)。
接缝定义为从左到右或从上到下流动的连接像素,前提是它们穿过图像的整个宽度/高度。

调用 transfrom.seam_carve(image, mag, ‘vertical’, numSeams) 来进行接缝雕刻

  • 原始图像,要调整大小的输入图像。
  • 能量图,可以从原始图像得到能量图。能量图应该代表图像中最显著的区域。通常是梯度幅度表示(即Sobel、Scharr等算子的输出)、熵映射或显著性映射。使用此图像作为输入,可以计算梯度大小作为能量图;
  • 方向 垂直或水平
  • 移除的像素大小

接缝雕刻算法原理?

  1. 接缝雕刻算法的工作原理是寻找连接的像素,称为低能量(即最不重要的)接缝,从左到右或从上到下遍历整个图像。

  2. 然后从原始图像中删除这些接缝,允许调整图像大小,同时保留最显著的区域(原始算法还支持添加接缝,允许增加图像大小)。

  3. 这些接缝通过动态规划有效地计算,并按其能量排序。低能量接缝放在列表的前面,而高能量接缝放在列表的后面。

  4. 调整图像的大小,可以移除能量较低的接缝以对图像进行下采样,或者复制能量较低的接缝以对图像进行上采样。

接缝雕刻的目的是调整图像本身的大小,并且仍然保留图像中最显著(即“有趣”)的区域。
使用传统的调整大小的方法会改变整个图像的尺寸,而不需要考虑确定图像的哪个部分最重要或最不重要。

Seam carving应用从能量图导出的启发式/路径查找来确定可以删除/复制图像的哪些区域,以确保(1)保留图像的所有“有趣”区域,(2)以美观的方式完成。
以一种美观的方式保存图像中最有趣的区域要比听起来困难得多。虽然接缝雕刻看起来很神奇,但实际上并非如此——而且它也有其局限性。接缝雕刻也有其局限性;

3. 安装——鉴于算法的专利原因,0.16以上版本均去掉了接缝雕刻算法;

在这里插入图片描述安装哪个版本可参考:这个网站
如下,比0.16版本低的均可一试;本文用如下版本ok;

  • windows 10
  • python 3.7.4
  • numpy 1.19.5+mkl
  • scipy 1.6.0
  • scikit-learn 0.24.1
  • scikit-image 0.14.4
    在这里插入图片描述

4. 源码

# USAGE
# python seam_carving.py --image images/as.jpg
# python seam_carving.py --image images/as.jpg --direction horizontal

import argparse

import cv2
import imutils
from skimage import filters
# 导入必要的包
from skimage import transform

# 构建命令行参数及解析
# --image 输入图像路径
# --direction 应用接缝雕刻,移除相同像素的方向 水平或垂直
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True,
                help="path to input image file")
ap.add_argument("-d", "--direction", type=str,
                default="vertical", help="seam removal direction")
args = vars(ap.parse_args())

# 加载图像,并转换为灰度图
image = cv2.imread(args["image"])
image = imutils.resize(image, width=250)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 计算Sobel梯度幅值表示(即能量图)
mag = filters.sobel(gray.astype("float"))
cv2.imshow("mag", mag)
cv2.waitKey(0)

# 展示原始图像
cv2.imshow("Original", image)
# cv2.waitKey(0)

# 函数只支持下采样图像-不提供上采样支持。
# 遍历接缝上打圈以移除
for numSeams in range(20, 80, 20):
    # 执行接缝雕刻,移除图像中的帧数--“垂直”剪切将更改图像高度,“水平”剪切更改图像宽度
    carved = transform.seam_carve(image, mag, args["direction"],
                                  numSeams)
    # 新的雕刻图像尺寸打印到终端
    print("[INFO] removing {} seams; new size: "
          "w={}, h={}".format(numSeams, carved.shape[1],
                              carved.shape[0]))

    # 展示雕刻算法的输出
    cv2.imshow("Carved", carved)
    cv2.waitKey(0)

参考

猜你喜欢

转载自blog.csdn.net/qq_40985985/article/details/113785504
今日推荐