简体   繁体   English

无法使用Python分割影像

[英]Unable to Split Image using Python

I need to split or crop my image into several boxes showing in the image. 我需要将图像拆分或裁剪为几个在图像中显示的框。 My code is given below which can split an Image but I am not be able to create 15 different boxes using my code. 下面给出了我的代码,该代码可以拆分图像,但是我无法使用我的代码创建15个不同的框。

My code is given below: 我的代码如下:

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

Now I want to crop or split it 15 different boxes available in the image attached here. 现在,我想将其裁剪或分割为15个不同的框,可在此处附加的图像中使用。 I am not be able to finding out any solution. 我找不到任何解决方案。 在此处输入图片说明

OpenCV: findContours OpenCV:findContours

An easy solution could be to use the built-in function from OpenCV findContours 一个简单的解决方案是使用OpenCV findContours中的内置功能

It will find all the contours present in your image (returned as a list of contour), in your example there are great chances that it will detect your boxes. 它会找到图像中存在的所有轮廓 (作为轮廓列表返回),在您的示例中,很有可能会检测到盒子。
Then you can iterate through this list to get the bounding boxes of your contour. 然后,您可以遍历此列表以获取轮廓的边界框。 From there you can create your sub images by slicing the original images with the bounding box coordinates. 在此处,您可以通过将原始图像与边界框坐标进行切片来创建子图像。

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

Official tutorial to use cv2.findContours: 使用cv2.findContours的官方教程:
https://docs.opencv.org/3.3.1/d4/d73/tutorial_py_contours_begin.html https://docs.opencv.org/3.3.1/d4/d73/tutorial_py_contours_begin.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM