getMaxRect.pyx 2.53 KB
Newer Older
Josef Brandt's avatar
Josef Brandt committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
GEPARD - Gepard-Enabled PARticle Detection
Copyright (C) 2018  Lars Bittrich and Josef Brandt, Leibniz-Institut für 
Polymerforschung Dresden e. V. <bittrich-lars@ipfdd.de>    

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program, see COPYING.  
If not, see <https://www.gnu.org/licenses/>.
"""

import numpy as np

cimport numpy as np
cimport cython

NP_INT32 = np.int32
ctypedef np.int32_t INT32_t

@cython.boundscheck(False)           # assume: no index larger than N-1
@cython.wraparound(False)            # assume: no neg. index
def findMaxRect(np.ndarray[np.uint8_t, ndim=2] img):
   
    '''http://stackoverflow.com/a/30418912/5008845'''
    cdef int nrows, ncols, row, col, dh, height, width, minw, area, max_area
    cdef np.ndarray[INT32_t, ndim=2] w, h    
    cdef np.ndarray[INT32_t, ndim=1] rectangle
    rectangle = np.zeros(6, dtype=NP_INT32)
    nrows, ncols = img.shape[0], img.shape[1]
    w = np.zeros((nrows, ncols), dtype=NP_INT32)
    h = np.zeros((nrows, ncols), dtype=NP_INT32)
    max_area = 0

    for row in range(nrows):
        for col in range(ncols):
            if img[row, col] == 1:
                continue
            
            if row == 0:
                h[row, col] = 1
            else:
                h[row, col] = h[row-1, col]+1
                
            if col == 0:
                w[row, col] = 1
            else:
                w[row, col] = w[row, col-1]+1
                
            minw = w[row, col]
            for dh in range(h[row, col]):
                minw = min(minw, w[row-dh, col])
                area = (dh+1)*minw
                if area > max_area:
                    max_area = area
                    rectangle[0], rectangle[1] = row-dh, col-minw+1
                    rectangle[2], rectangle[3] = row, col
                    rectangle[4], rectangle[5] = dh+1, minw
    
    point1 = rectangle[0], rectangle[1]
    point2 = rectangle[2], rectangle[3]
    height, width = rectangle[4], rectangle[5]
    return point1, point2, width, height, max_area