从多个分裂 [英] Single splitting from multiple

查看:109
本文介绍了从多个分裂的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要将我的图像拆分或裁剪为多张图像.下面给出了我的代码,该代码可以将一个图像分成4个部分,但是我无法使用我的代码创建6个或9个部分.我是初学者,所以找不到解决方法.

I need to split or crop my image into several images. My code is given below which can split an Image into 4 pieces but I am not be able to create 6 or 9 pieces using my code. I am a beginner so unable to find out a solution.

我的代码如下:

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那样将其尽可能多地分割,那么该怎么做?

The code above first split an image into two parts and then from that two parts it divide that image into 4 parts.But if I need to split it as much as I need like 6,9,15 then how to do this?

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

This is my image which I need to split into 6 separate boxes:

推荐答案

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

First of all, for non-4 numbers, you need a function to split the number into factors of almost equal size. For 4, you have done it by hand, 2x2. So, the following code would dothe splitting as you wish (works on 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])

重要注意事项::如果无法通过因素将图像大小整除,则此代码将裁剪右侧/底部的一些像素!但是处理这种情况并不是很困难.

Important note: If the image size is not divisible by the factors, then some pixels to the right / bottom will be cropped by this code! But it is not very hard to handle this situation.

这篇关于从多个分裂的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆