从多个中分离出单个

2023-12-19

我需要将图像分割或裁剪为多张图像。下面给出了我的代码,它可以将图像分成 4 块,但我无法使用我的代码创建 6 或 9 块。我是初学者,所以无法找到解决方案。

我的代码如下:

from scipy import misc

# Read the image
img = misc.imread("Imaagi.jpg")
height, width, _ = img.shape

# Cut the image in half
width_cutoff = width // 2
s1 = img[:, :width_cutoff, :]
s2 = img[:, width_cutoff:, :]


# Save each half
misc.imsave("1.jpg", s1)
misc.imsave("2.jpg", s2)

img = misc.imread("1.jpg")
height, width, _ = img.shape
height_cutoff = height // 2

s3 = img[:height_cutoff, :, :]
s4 = img[height_cutoff:, :, :]

misc.imsave("111.jpg", s3)
misc.imsave("222.jpg", s4)  

上面的代码首先将图像分割成两部分,然后从这两部分中将该图像分割成 4 部分。但是如果我需要将其分割为 6、9、15 等数量,那么该怎么做呢?

这是我的图像,我需要将其分成 6 个单独的框:


首先,对于非 4 数字,您需要一个函数将数字拆分为几乎相等大小的因子。对于 4,您已手动完成,2x2。因此,以下代码将按照您的意愿进行分割(适用于 python 3.6.3,scipy 1.1.0):

# -*- coding: utf-8 -*-

import math, cv2
from scipy import misc
import numpy

def getFactors(num):
    """
    Split the input number into factors nearest to its square root. May not be
    the most efficient for large numbers, but will do for numbers smaller than 1000.
    """
    sqt = int(math.sqrt(num))
    if (num % sqt) == 0:
        return (sqt,int(num/sqt))

    num1 = sqt
    num2 = sqt
    while True:
        num1 += 1
        num2 -= 1
        if (num1 >= num) or (num2 <= 0):
            return (num, 1)
        if (num % num1) == 0:
            return (num1, int(num/num1))
        if (num % num2) == 0:
            return (num2, int(num/num2))
    return

def splitImage(img, numsplits):
    """
    Split the input image into number of splits provided by the second argument.
    The results are stored in a numpy array res and returned. The last index of the
    res array indexes the individual parts.
    """
    # Get the factors for splitting. So if the number of splits is 9, then (3,3)
    # or if 6 then (2,3) etc.
    factors = getFactors(numsplits)
    # Height and width of each split
    h = int(img.shape[0] / factors[0])
    w = int(img.shape[1] / factors[1])
    # Handle both color and B&W images
    if img.ndim >= 3:
        size = (h,w,img.shape[2],numsplits)
    else:
        size = (h,w,numsplits)
    # Initialize the result array
    res = numpy.ndarray( size, dtype = img.dtype )
    # Iterate through the number of factors to split the source image horizontally
    # and vertically, and store the resultant chunks
    for i in range(factors[0]):
        for j in range(factors[1]):
            if img.ndim >= 3:
                res[:,:,:,((i*factors[1])+j)] = img[(i*h):((i+1)*h), (j*w):((j+1)*w),:]
            else:
                res[:,:,((i*factors[1])+j)] = img[(i*h):((i+1)*h), (j*w):((j+1)*w)]

    return res

def cropImage(img):
    """
    Detect lines in the image to crop it so that the resultant image can be split well.
    We use here Canny edge detection followed by Hough Line Transform.
    """
    # Convert image to grayscale
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # Detect edges and lines
    edges = cv2.Canny(gray, 50, 150, apertureSize = 3)
    lines = cv2.HoughLines(edges, 1, numpy.pi/90, 200)

    min_x = img.shape[0]
    max_x = 0
    min_y = img.shape[1]
    max_y = 0
    # Find the extremal horizontal and vertical coordinates to crop
    for i in range(len(lines[:,0,0])):
        rho = lines[i,0,0]
        theta = lines[i,0,1]
        a = numpy.cos(theta)
        b = numpy.sin(theta)
        x = a*rho
        y = b*rho

        if abs(a) < 1e-06 :
            if min_y > int(y):
                min_y = int(y)
            if max_y < int(y):
                max_y = int(y)
        if abs(b) < 1e-06 :
            if min_x > int(x):
                min_x = int(x)
            if max_x < int(x):
                max_x = int(x)

    return img[min_y:max_y, min_x:max_x, :]

# Read image     
img = misc.imread('tmp.png')
# Crop the image
img = cropImage(img)
# Call the splitter function
res = splitImage(img, 6)
# Save the results to files
for i in range(res.shape[-1]):
    if img.ndim >= 3:
        misc.imsave('res_{0:03d}.png'.format(i),res[:,:,:,i])
    else:
        misc.imsave('res_{0:03d}.png'.format(i),res[:,:,i])

重要的提示:如果图像大小不能被这些因子整除,则此代码将裁剪右侧/底部的一些像素!但处理这种情况并不难。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从多个中分离出单个 的相关文章

随机推荐