python 使用opencv库通过智能裁剪生成给定形状的缩略图。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python 使用opencv库通过智能裁剪生成给定形状的缩略图。相关的知识,希望对你有一定的参考价值。

# Copyright (c) 2017 Sudipto Chandra <dipu.sudipta@gmail.com>

# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:

# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

import os
import sys
from glob import glob

import cv2
import numpy as np

###################################################################################

def get_thumb(img, width, height):
    """Gets the thumbnail from the image"""
    row, col = img.shape[:2]
    # rescale
    m = get_scale(row, col, height, width)
    size = int(col * m), int(row * m)
    img = cv2.resize(img, size)
    # autocrop
    x, y = auto_crop(img, width, height)
    crop = img[x:x+height, y:y+width]
    return crop
# end def


def get_scale(x1, y1, x2, y2):
    """Gets the rescale amount from original(x1, y1) and target(x2, y2) size"""
    if x1 < x2:
        if y1 < y2:
            if x1 < y1:
                return x2 / x1
            else:
                return y2 / y1
            # end if
        else:
            return x2 / x1
        # end  if
    else:
        if y1 < y2:
            return y2 / y1
        else:
            if x1 < y1:
                return x2 / x1
            else:
                return y2 / y1
            # end if
        # end  if
    # end if
# end def


def auto_crop(img, width, height):
    """Get crop area from image"""
    row, col = img.shape[:2]
    # get edge imagea
    edges = cv2.Canny(img, 100, 200)
    # use border
    edges[:, :2] = 0
    edges[:, col-2:] = 0
    edges[:2, :] = 0
    edges[row-2:, :] = 0
    # horizontal crop
    x = 0
    hor = np.sum(edges, axis=1)
    for i in range(row - height):
        if compare(hor, i, x, height):
            x = i
        # end if
    # end for
    # vertical crop
    y = 0
    ver = np.sum(edges, axis=0)
    for j in range(col - width):
        if compare(ver, j, y, width):
            y = j
        # end if
    # end for
    return x, y
# end def


def compare(arr, pos1, pos2, siz):
    x1 = arr[pos1] + arr[pos1 + siz]
    x2 = arr[pos2] + arr[pos2 + siz]
    y1 = np.sum(arr[pos1+1:pos1+siz-2])
    y2 = np.sum(arr[pos2+1:pos2+siz-2])
    #return x1 < x2 and y1 >= y2
    return y1 > y2 or (y1 == y2 and x1 < x2)
# end if

###################################################################################

def main():
    """Main method"""
    def show(file):
        img = cv2.imread(file)
        if img is not None:
            img = get_thumb(img, width, height)
            cv2.imshow('{} @ {} x {}'.format(file, width, height), img)
            cv2.waitKey()
        # end if
    # end def
    try:
        file = os.path.abspath(sys.argv[1])
        width = int(sys.argv[2])
        height = int(sys.argv[3])
        if os.path.isdir(file):
            for f in sorted(glob(os.path.join(file, '*.*'))):
                show(f)
            # end for
        else:
            show(file)
        # end if
    except IndexError:
        print_help()
    except:
        print_help()
        raise
    # end try
# end def


def print_help():
    """Shows help"""
    print('Extracts thumbnail from an image.', end='\n\n')
    print('$> python thumb.py <image_path> <width> <height>', end='\n\n')
    print(' image_path  The image file or some directory containing images')
    print('      width  Thumbnail width')
    print('     height  Thumbnail height')
    print()
# end def


if __name__ == '__main__':
    main()
# end if

以上是关于python 使用opencv库通过智能裁剪生成给定形状的缩略图。的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Python 和 OpenCV 裁剪图像中的多个 ROI

如何在python opencv中简单地裁剪边界框[重复]

minAreaRect OpenCV [Python] 返回的裁剪矩形

Python OpenCV给证件照换底色

python-opencv-图片的裁剪

如何使用 Python 图像库裁剪通过鼠标单击选择的区域?