o
    jt(                     @  sX   d dl mZ d dlZddlmZmZ dZg dZg dZG dd	 d	Z	G d
d dZ
dS )    )annotationsN   )Image_imagingmorphi   )	      r         r            )	r   r   r   r   r	   r   r
   r   r   c                   @  sZ   e Zd ZdZ	d#d$d	d
Zd%ddZd&ddZd'ddZd(ddZd)dd Z	d&d!d"Z
dS )*
LutBuilderaT  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()

    Npatternslist[str] | Noneop_name
str | NonereturnNonec                 C  sz   d| _ |dur/ddgdgddgdgddgg dd	}||vr(d
| d}t||| | _dS |dur8|| _dS g | _dS )a  
        :param patterns: A list of input patterns, or None.
        :param op_name: The name of a known pattern. One of "corner", "dilation4",
           "dilation8", "erosion4", "erosion8" or "edge".
        :exception Exception: If the op_name is not recognized.
        N1:(... ... ...)->0z4:(00. 01. ...)->1z4:(... .0. .1.)->1z4:(... .0. ..1)->1z4:(... .1. .0.)->0z4:(... .1. ..0)->0)r   z4:(.0. .1. ...)->1z4:(01. .1. ...)->1)ZcornerZ	dilation4Z	dilation8Zerosion4Zerosion8edgezUnknown pattern !)lut	Exceptionr   )selfr   r   Zknown_patternsmsg r   O/var/www/html/Deteccion_Ine/venv/lib/python3.10/site-packages/PIL/ImageMorph.py__init__A   s    	

zLutBuilder.__init__	list[str]c                 C  s   |  j |7  _ dS )z\
        Append to list of patterns.

        :param patterns: Additional patterns.
        N)r   )r   r   r   r   r   add_patternsb   s   zLutBuilder.add_patterns	bytearrayc                   s0   ddgd t  fddttD | _| jS )z
        Set the current LUT, and return it.

        This is the default LUT that patterns will be applied against when building.
        r   r      c                 3  s     | ]}| @ d k V  qdS )r   Nr   ).0imsymbolsr   r   	<genexpr>r   s    z/LutBuilder.build_default_lut.<locals>.<genexpr>)r    rangeLUT_SIZEr   r   r   r$   r   build_default_lutj   s   zLutBuilder.build_default_lutbytearray | Nonec                 C  s   | j S )z)
        Returns the current LUT
        r   r*   r   r   r   get_lutu   s   zLutBuilder.get_lutpatternstrpermutation	list[int]c                   s(   t |dksJ d fdd|D S )zuTakes a pattern and a permutation and returns the
        string permuted according to the permutation list.
        	    c                 3  s    | ]} | V  qd S )Nr   )r"   pr/   r   r   r'      s    z-LutBuilder._string_permute.<locals>.<genexpr>)lenjoin)r   r/   r1   r   r6   r   _string_permute{   s   zLutBuilder._string_permutebasic_patternoptionsbasic_resultintlist[tuple[str, int]]c           	      C  s   ||fg}d|v r%|d d }t dD ]}|| |d d t|f qd|v rCt|}|d| D ]\}}|| |t|f q3d|v rqt|}|d| D ]\}}|d	d
dd	d
d}dt| }|||f qQ|S )zTakes 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   MNN0Z1)r(   appendr9   ROTATION_MATRIXr7   MIRROR_MATRIXreplacer=   )	r   r:   r;   r<   r   resr#   nr/   r   r   r   _pattern_permute   s$   
zLutBuilder._pattern_permutec                 C  sD  |    | jdusJ g }| jD ]<}td|dd}|s(d| d }t||d}|d}t|d	}|d
ddd}|| 	|||7 }qg }|D ]}|d dddd}|
t||d f qQttD ].}	t|	dd }
ddt|
  |
 ddd }
|D ]\}}||
rddg| | j|	< qqp| jS )zoCompile all patterns into a morphology LUT, and return it.

        This is the data to be passed into MorphOp.Nz(\w):?\s*\((.+?)\)\s*->\s*(\d)
r4   zSyntax error in pattern ""r   r   r    r   .Xz[01]rC   r3   r@   )r+   r   r   researchrI   r   groupr=   rL   rF   compiler(   r)   binr7   match)r   r   r5   r%   r   r;   r/   resultZcompiled_patternsr#   Z
bitpatternrr   r   r   	build_lut   s4   



zLutBuilder.build_lut)NN)r   r   r   r   r   r   )r   r   r   r   )r   r    )r   r,   )r/   r0   r1   r2   r   r0   )r:   r0   r;   r0   r<   r=   r   r>   )__name__
__module____qualname____doc__r   r   r+   r.   r9   rL   rZ   r   r   r   r   r      s    $
!



 r   c                   @  s^   e Zd ZdZ			dd ddZd!ddZd"ddZd"ddZd#ddZd#ddZ	d$ddZ
dS )%MorphOpz*A class for binary morphological operatorsNr   r,   r   r   r   r   r   r   c                 C  s.   |du r|du r|| _ dS t|| | _ dS )a  Create a binary morphological operator.

        If the LUT is not provided, then it is built using LutBuilder from the op_name
        or the patterns.

        :param lut: The LUT data.
        :param patterns: A list of input patterns, or None.
        :param op_name: The name of a known pattern. One of "corner", "dilation4",
        "dilation8", "erosion4", "erosion8", "edge".
        :exception Exception: If the op_name is not recognized.
        N)r   r   rZ   )r   r   r   r   r   r   r   r      s   
zMorphOp.__init__imageImage.Imagetuple[int, Image.Image]c                 C  s`   | j du rd}t||jdvrd}t|t|j|j}tt	| j |
 |
 }||fS )a9  Run a single morphological operation on an image.

        Returns a tuple of the number of changed pixels and the
        morphed image.

        :param image: A 1-mode or L-mode image.
        :exception Exception: If the current operator is None.
        :exception ValueError: If the image is not 1 or L mode.NNo operator loadedrE   LImage mode must be 1 or L)r   r   mode
ValueErrorr   newsizer   applybytesgetim)r   r`   r   Zoutimagecountr   r   r   rk      s   
	
zMorphOp.applylist[tuple[int, int]]c                 C  sB   | j du rd}t||jdvrd}t|tt| j | S )ax  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. See
        :ref:`coordinate-system`.

        :param image: A 1-mode or L-mode image.
        :exception Exception: If the current operator is None.
        :exception ValueError: If the image is not 1 or L mode.Nrc   rd   rf   )r   r   rg   rh   r   rW   rl   rm   r   r`   r   r   r   r   rW      s   


zMorphOp.matchc                 C  s$   |j dvrd}t|t| S )a!  Get a list of all turned on pixels in a 1 or L mode image.

        Returns a list of tuples of (x,y) coordinates of all non-empty pixels. See
        :ref:`coordinate-system`.

        :param image: A 1-mode or L-mode image.
        :exception ValueError: If the image is not 1 or L mode.rd   rf   )rg   rh   r   get_on_pixelsrm   rp   r   r   r   rq     s   
	zMorphOp.get_on_pixelsfilenamer0   c                 C  s\   t |d}t| | _W d   n1 sw   Y  t| jtkr,d| _d}t|dS )z
        Load an operator from an mrl file

        :param filename: The file to read from.
        :exception Exception: If the length of the file data is not 512.
        rbNzWrong size operator file!)openr    readr   r7   r)   r   )r   rr   fr   r   r   r   load_lut  s   zMorphOp.load_lutc                 C  sR   | j du rd}t|t|d}|| j  W d   dS 1 s"w   Y  dS )z
        Save an operator to an mrl file.

        :param filename: The destination file.
        :exception Exception: If the current operator is None.
        Nrc   wb)r   r   rt   write)r   rr   r   rv   r   r   r   save_lut*  s   
"zMorphOp.save_lutc                 C  s
   || _ dS )zU
        Set the LUT from an external source

        :param lut: A new LUT.
        Nr-   )r   r   r   r   r   set_lut7  s   
zMorphOp.set_lut)NNN)r   r,   r   r   r   r   r   r   )r`   ra   r   rb   )r`   ra   r   ro   )rr   r0   r   r   )r   r,   r   r   )r[   r\   r]   r^   r   rk   rW   rq   rw   rz   r{   r   r   r   r   r_      s    




r_   )
__future__r   rR   r4   r   r   r)   rG   rH   r   r_   r   r   r   r   <module>   s    1