我需要将我的图像分割或裁剪成几幅图像。下面给出了我的代码,它可以将一个图像分割成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 parts.But,如果我需要像6、9、15这样将图像拆分,那么如何实现呢?
这是我的照片,我需要分成六个单独的盒子:
发布于 2018-07-16 12:44:48
首先,对于非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])
重要注意事项:,如果图像大小不能被因子整除,那么右/底部的一些像素将被这段代码裁剪!但处理这种情况并不难。
https://stackoverflow.com/questions/51360609
复制相似问题