î
úÙ Xe   ã               @   sb   d  d l  m Z d  d l  m Z d  d l Z d
 Z Gd d „  d e ƒ Z Gd d	 „  d	 e ƒ Z d S)é    )ÚImage)Ú_imagingmorphNé   é	   c               @   sp   e  Z d  Z d Z d d d d „ Z d d „  Z d d „  Z d	 d
 „  Z d d „  Z d d „  Z	 d d „  Z
 d S)Ú
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()

    Nc             C   s¾   | d  k	 r | |  _  n	 g  |  _  d  |  _ | d  k	 rº i d d g d 6d g d 6d d g d 6d g d	 6d d
 g d 6d d d g d 6} | | k rª t d | d ƒ ‚ n  | | |  _  n  d  S)Nz1:(... ... ...)->0z4:(00. 01. ...)->1Zcornerz4:(... .0. .1.)->1Z	dilation4z4:(... .0. ..1)->1Z	dilation8z4:(... .1. .0.)->0Zerosion4z4:(... .1. ..0)->0Zerosion8z4:(.0. .1. ...)->1z4:(01. .1. ...)->1ZedgezUnknown pattern ú!)ÚpatternsÚlutÚ	Exception)Úselfr   Úop_nameZknown_patterns© r   úK/home/ubuntu/projects/ifolica/lib/python3.4/site-packages/PIL/ImageMorph.pyÚ__init__2   s(    		




zLutBuilder.__init__c             C   s   |  j  | 7_  d  S)N)r   )r   r   r   r   r   Úadd_patternsK   s    zLutBuilder.add_patternsc                sA   d d g ‰ d ‰  t  ‡  ‡ f d d †  t t ƒ Dƒ ƒ |  _ d  S)Nr   r   é   c                s$   g  |  ] } ˆ | ˆ  @d  k ‘ q S)r   r   )Ú.0Úi)ÚmÚsymbolsr   r   ú
<listcomp>Q   s   	 z0LutBuilder.build_default_lut.<locals>.<listcomp>é   )Ú	bytearrayÚrangeÚLUT_SIZEr	   )r   r   )r   r   r   Úbuild_default_lutN   s    zLutBuilder.build_default_lutc             C   s   |  j  S)N)r	   )r   r   r   r   Úget_lutS   s    zLutBuilder.get_lutc                s8   t  | ƒ d k s t ‚ d j ‡  f d d †  | Dƒ ƒ S)z„string_permute takes a pattern and a permutation and returns the
        string permuted according to the permutation list.
        r   Ú c                s   g  |  ] } ˆ  | ‘ q Sr   r   )r   Úp)Úpatternr   r   r   [   s   	 z.LutBuilder._string_permute.<locals>.<listcomp>)ÚlenÚAssertionErrorÚjoin)r   r   Zpermutationr   )r   r   Ú_string_permuteV   s    zLutBuilder._string_permutec       	      C   sŒ  | | f g } d | k r… | d d } xY t  d ƒ D]H } | j |  j | d d d d d d d d d d	 d
 g	 ƒ | f ƒ q6 Wn  d | k rû t | ƒ } x[ | d | … D]F \ } } | j |  j | d
 d d d	 d d d d d g	 ƒ | f ƒ q® Wn  d | k rˆt | ƒ } xr | d | … D]] \ } } | j d d ƒ j d d ƒ j d d ƒ } d d t | ƒ } | j | | f ƒ q$Wn  | S)zÉpattern_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.Ú4r   r   r   é   é   é   é   é   é   ÚMÚNÚ0ÚZÚ1z%déÿÿÿÿr0   )r   Úappendr#   r    ÚreplaceÚint)	r   Zbasic_patternÚoptionsZbasic_resultr   Úresr   Únr   r   r   r   Ú_pattern_permute]   s2    	 	 zLutBuilder._pattern_permutec       
      C   sÌ  |  j  ƒ  g  } x¶ |  j D]« } t j d | j d d ƒ ƒ } | s[ t d | d ƒ ‚ n  | j d ƒ } | j d ƒ } t | j d ƒ ƒ } | j d	 d ƒ j d d ƒ } | |  j | | | ƒ 7} q Wxg t	 t
 | ƒ ƒ D]S } | | d
 j d d ƒ j d d ƒ } t j | ƒ } | | | d f | | <qÜ Wx t	 t ƒ D] } t | ƒ d d … } d d t
 | ƒ | d d d … } x= | D]5 \ } }	 | j | ƒ rˆd
 d g |	 |  j | <qˆqˆWq@W|  j S)zlCompile all patterns into a morphology lut.

        TBD :Build based on (file) morphlut:modify_lut
        z(\w*):?\s*\((.+?)\)\s*->\s*(\d)Ú
r   zSyntax error in pattern "ú"r   r*   r&   ú r   Ú.ÚXz[01]Nr-   r   r0   )r   r   ÚreÚsearchr2   r
   Úgroupr3   r7   r   r    Úcompiler   ÚbinÚmatchr	   )
r   r   r   r   r4   r   Úresultr   Z
bitpatternÚrr   r   r   Ú	build_lut‚   s.    
&%"zLutBuilder.build_lut)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r#   r7   rE   r   r   r   r   r      s   "%r   c               @   ss   e  Z d  Z d Z d d d d d „ Z d d „  Z d d „  Z d	 d
 „  Z d d „  Z d d „  Z	 d d „  Z
 d S)ÚMorphOpz*A class for binary morphological operatorsNc             C   s[   | |  _  | d k	 r0 t d | ƒ j ƒ  |  _  n' | d k	 rW t d | ƒ j ƒ  |  _  n  d S)z&Create a binary morphological operatorNr   r   )r	   r   rE   )r   r	   r   r   r   r   r   r   ¶   s
    	zMorphOp.__init__c             C   s‹   |  j  d k r t d ƒ ‚ n  | j d k r< t d ƒ ‚ n  t j | j | j d ƒ } t j t |  j  ƒ | j	 j
 | j	 j
 ƒ } | | f S)z‡Run a single morphological operation on an image

        Returns a tuple of the number of changed pixels and the
        morphed imageNzNo operator loadedÚLz0Image must be binary, meaning it must use mode L)r	   r
   Úmoder   ÚnewÚsizer   ÚapplyÚbytesÚimÚid)r   ÚimageZoutimageÚcountr   r   r   rO   Á   s    $zMorphOp.applyc             C   s[   |  j  d k r t d ƒ ‚ n  | j d k r< t d ƒ ‚ n  t j t |  j  ƒ | j j ƒ S)zªGet a list of coordinates matching the morphological operation on
        an image.

        Returns a list of tuples of (x,y) coordinates
        of all matching pixels.NzNo operator loadedrK   z0Image must be binary, meaning it must use mode L)r	   r
   rL   r   rB   rP   rQ   rR   )r   rS   r   r   r   rB   Ð   s
    zMorphOp.matchc             C   s1   | j  d k r t d ƒ ‚ n  t j | j j ƒ S)z‹Get a list of all turned on pixels in a binary image

        Returns a list of tuples of (x,y) coordinates
        of all matching pixels.rK   z0Image must be binary, meaning it must use mode L)rL   r
   r   Úget_on_pixelsrQ   rR   )r   rS   r   r   r   rU   Ý   s    zMorphOp.get_on_pixelsc          	   C   s^   t  | d ƒ  } t | j ƒ  ƒ |  _ Wd QXt |  j ƒ d k rZ d |  _ t d ƒ ‚ n  d S)z!Load an operator from an mrl fileÚrbNi    zWrong size operator file!)Úopenr   Úreadr	   r    r
   )r   ÚfilenameÚfr   r   r   Úload_lutç   s
    	zMorphOp.load_lutc          	   C   sJ   |  j  d k r t d ƒ ‚ n  t | d ƒ  } | j |  j  ƒ Wd QXd S)zSave an operator to an mrl fileNzNo operator loadedÚwb)r	   r
   rW   Úwrite)r   rY   rZ   r   r   r   Úsave_lutð   s    zMorphOp.save_lutc             C   s   | |  _  d S)z#Set the lut from an external sourceN)r	   )r   r	   r   r   r   Úset_lut÷   s    zMorphOp.set_lut)rF   rG   rH   rI   r   rO   rB   rU   r[   r^   r_   r   r   r   r   rJ   ³   s   
	rJ   i   )ZPILr   r   r=   r   Úobjectr   rJ   r   r   r   r   Ú<module>   s
   ¤