Невозможно разделить изображение с помощью Python

1

Мне нужно разделить или обрезать изображение в несколько ящиков, отображаемых на изображении. Ниже приведен мой код, который может разбивать изображение, но я не могу создать 15 разных ящиков, используя свой код.

Мой код приведен ниже:

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])

Теперь я хочу обрезать или разделить его на 15 различных ящиков, доступных на прилагаемом изображении. Я не могу найти решение. Изображение 174551

Теги:
image-processing
python-3.x
image
python-imaging-library

1 ответ

0

OpenCV: findContours

Легким решением может быть использование встроенной функции из OpenCV findContours

Он найдет все контуры, присутствующие в вашем изображении (возвращается как список контуров), в вашем примере есть большие шансы, что он обнаружит ваши поля.
Затем вы можете перебирать этот список, чтобы получить ограничивающие прямоугольники вашего контура. Оттуда вы можете создавать свои вспомогательные изображения, нарезая исходные изображения с помощью координат рамки.

_, contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for contour in countours:
    (_x, _y, w, h) = cv2.boundingRect(contour)

Официальный учебник по использованию cv2.findContours:
https://docs.opencv.org/3.3.1/d4/d73/tutorial_py_contours_begin.html

  • 0
    Спасибо за ваше предложение. Я не получаю точно. Я новичок. Можете ли вы показать мне, как это сделать?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню