3 }\O @sLddlmZddlmZmZddlZd ZGdddeZGdd d eZ dS) )print_function)Image _imagingmorphN c@sJeZdZdZdddZddZddZd d Zd d Zd dZ ddZ dS) LutBuildera~A class for building a MorphLut from a descriptive language The input patterns is a list of a strings sequences like these:: 4:(... .1. 111)->1 (whitespaces including linebreaks are ignored). The option 4 describes a series of symmetry operations (in this case a 4-rotation), the pattern is described by: - . or X - Ignore - 1 - Pixel is on - 0 - Pixel is off The result of the operation is described after "->" string. The default is to return the current pixel value, which is returned if no other match is found. Operations: - 4 - 4 way rotation - N - Negate - 1 - Dummy op for no other operation (an op must always be given) - M - Mirroring Example:: lb = LutBuilder(patterns = ["4:(... .1. 111)->1"]) lut = lb.build_lut() NcCsr|dk r||_ng|_d|_|dk rnddgdgddgdgddgdddgd }||krdtd |d |||_dS) Nz1:(... ... ...)->0z4:(00. 01. ...)->1z4:(... .0. .1.)->1z4:(... .0. ..1)->1z4:(... .1. .0.)->0z4:(... .1. ..0)->0z4:(.0. .1. ...)->1z4:(01. .1. ...)->1)ZcornerZ dilation4Z dilation8Zerosion4Zerosion8ZedgezUnknown pattern !)patternslut Exception)selfr op_nameZknown_patternsrf/private/var/folders/pf/wv4htv3x0qs2c2mp0dnn0kchsvlck3/T/pip-install-i584jbuk/Pillow/PIL/ImageMorph.py__init__3s& zLutBuilder.__init__cCs|j|7_dS)N)r )r r rrr add_patternsLszLutBuilder.add_patternscs.ddgdtfddttD|_dS)Nrrc3s|]}|@dkVqdS)rNr).0i)msymbolsrr Rsz/LutBuilder.build_default_lut..) bytearrayrangeLUT_SIZEr )r r)rrrbuild_default_lutOszLutBuilder.build_default_lutcCs|jS)N)r )r rrrget_lutTszLutBuilder.get_lutcs(t|dkstdjfdd|DS)zstring_permute takes a pattern and a permutation and returns the string permuted according to the permutation list. rc3s|]}|VqdS)Nr)rp)patternrrr\sz-LutBuilder._string_permute..)lenAssertionErrorjoin)r r Z permutationr)r r_string_permuteWszLutBuilder._string_permutec Cs||fg}d|kr`|dd}x@tdD]4}|j|j|dddddddddd d g |fq(Wd |krt|}x@|d|D]0\}}|j|j|d ddd dddddg |fq~Wd |krt|}xN|d|D]>\}}|jd djdd jdd}dt|}|j||fqW|S)zpattern_permute takes a basic pattern and its result and clones the pattern according to the modifications described in the $options parameter. It returns a list of all cloned patterns.4rrrMN0Z1r1)rappendr$r!replaceint) r Z basic_patternoptionsZ basic_resultr resrnr rrr_pattern_permute^s2     zLutBuilder._pattern_permutec CsL|jg}x~|jD]t}tjd|jdd}|s@td|d|jd}|jd}t|jd}|jd djdd}||j|||7}qWxFt |D]:\}}|d jd d jd d }tj |}||df||<qWxpt t D]d}t |dd}ddt||ddd}x0|D](\}} |j|rd dg| |j|<qWqW|jS)zlCompile all patterns into a morphology lut. TBD :Build based on (file) morphlut:modify_lut z(\w*):?\s*\((.+?)\)\s*->\s*(\d) rzSyntax error in pattern ""rr+r' r.Xz[01]Nr.rr1)rr researchr3r groupr4r8 enumeratecompilerrbinr!matchr ) r r rrr5r resultrZ bitpatternrrrr build_luts.     zLutBuilder.build_lut)NN) __name__ __module__ __qualname____doc__rrrrr$r8rGrrrrrs" %rc@sJeZdZdZdddZddZddZd d Zd d Zd dZ ddZ dS)MorphOpz*A class for binary morphological operatorsNcCs<||_|dk r t|dj|_n|dk r8t|dj|_dS)z&Create a binary morphological operatorN)r )r )r rrG)r r r r rrrrs zMorphOp.__init__cCsZ|jdkrtd|jdkr$tdtj|j|jd}tjt|j|j j |j j }||fS)zRun a single morphological operation on an image Returns a tuple of the number of changed pixels and the morphed imageNzNo operator loadedLz0Image must be binary, meaning it must use mode L) r r modernewsizerapplybytesimid)r imageZoutimagecountrrrrQs  z MorphOp.applycCs:|jdkrtd|jdkr$tdtjt|j|jjS)zGet a list of coordinates matching the morphological operation on an image. Returns a list of tuples of (x,y) coordinates of all matching pixels. See :ref:`coordinate-system`.NzNo operator loadedrMz0Image must be binary, meaning it must use mode L)r r rNrrDrRrSrT)r rUrrrrDs   z MorphOp.matchcCs |jdkrtdtj|jjS)zGet a list of all turned on pixels in a binary image Returns a list of tuples of (x,y) coordinates of all matching pixels. See :ref:`coordinate-system`.rMz0Image must be binary, meaning it must use mode L)rNr r get_on_pixelsrSrT)r rUrrrrWs zMorphOp.get_on_pixelsc CsDt|d}t|j|_WdQRXt|jtkr@d|_tddS)z!Load an operator from an mrl filerbNzWrong size operator file!)openrreadr r!rr )r filenamefrrrload_luts  zMorphOp.load_lutc Cs8|jdkrtdt|d}|j|jWdQRXdS)zSave an operator to an mrl fileNzNo operator loadedwb)r r rYwrite)r r[r\rrrsave_luts  zMorphOp.save_lutcCs ||_dS)z#Set the lut from an external sourceN)r )r r rrrset_lutszMorphOp.set_lut)NNN) rHrIrJrKrrQrDrWr]r`rarrrrrLs    rLi) __future__rrrrr>robjectrrLrrrrs