a
    d/                     @   s   d dl mZmZmZmZ d dlZd dlmZ d dlmZm	Z	 eje
e
ejddddZejejejejejdd	d
Zdejejeej ee ejdddZee
e
eeef dddZee edddZeeeee f eedddZdS )    )ListOptionalTupleUnionN)Tensor)KORNIA_CHECKKORNIA_CHECK_SHAPE)imagexycolorreturnc                 C   s   || dd||f< dS )al  Draws a pixel into an image.

    Args:
        image: the input image to where to draw the lines with shape :math`(C,H,W)`.
        x: the x coordinate of the pixel.
        y: the y coordinate of the pixel.
        color: the color of the pixel with :math`(C)` where :math`C` is the number of channels of the image.

    Return:
        Nothing is returned.
    N )r	   r
   r   r   r   r   Z/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/kornia/utils/draw.py_draw_pixel   s    r   )r	   p1p2r   r   c                    sr  t |dkst |dkr tdt |  dkr8td|d| dkrTtd|d | dks|d | dks|d dk s|d dk rtd|d | dks|d | dks|d dk s|d dk rtd	|| jtj}|| jtj}|| }|\}}|\}}||  || || ||   dk rZ     dkrn   }t|| t	||  }}t|| t	||  }} fd
d}	dkr|| dd||d |f< n dkr
|| dd|||d f< ndd|  k r"dk rnn nHt
||d D ]4}
t| |
|| |	|
d |d dkr4|d7 }q4n |dkrt
||d D ]4}t| ||| |	|d |d dk r|d7 }qn|dkrt
||d D ]4}t| ||| |	|d |d dkr|d8 }qn`d|  k r&dk rnn nDt
||d D ]4}
t| |
|| |	|
d |d dkr8|d8 }q8| S )a[  Draw a single line into an image.

    Args:
        image: the input image to where to draw the lines with shape :math`(C,H,W)`.
        p1: the start point [x y] of the line with shape (2).
        p2: the end point [x y] of the line with shape (2).
        color: the color of the line with shape :math`(C)` where :math`C` is the number of channels of the image.

    Return:
        the image with containing the line.

    Examples:
        >>> image = torch.zeros(1, 8, 8)
        >>> draw_line(image, torch.tensor([6, 4]), torch.tensor([1, 4]), torch.tensor([255]))
        tensor([[[  0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.],
                 [  0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.],
                 [  0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.],
                 [  0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.],
                 [  0., 255., 255., 255., 255., 255., 255.,   0.],
                 [  0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.],
                 [  0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.],
                 [  0.,   0.,   0.,   0.,   0.,   0.,   0.,   0.]]])
       zp1 and p2 must have length 2.   z%image must have 3 dimensions (C,H,W).r   z9color must have the same number of channels as the image.   zp1 is out of bounds.zp2 is out of bounds.c                    s    |  |   S )Nr   )r
   r   ABCr   r   line_equationb   s    z draw_line.<locals>.line_equationNg      ?)len
ValueErrorsizetodevicetorchint64minlongmaxranger   )r	   r   r   r   x1y1Zx2y2mr   ijr   r   r   	draw_line   sh    <<







r-   )r	   	rectangler   fillr   c                 C   s,  | j \}}}}|j \}}	}
||kr*td|
dkr:td|  }t|dddddddf d|d |dddddddf< t|dddddddf d|d |dddddddf< |du rtdg| ||	|}|du rd	}t|j dkr|||	|}|j \}}}|dkrD|d
krD|||	|}t	|D ]}t	|	D ]}|r|||ddddf | |ddt
|||df t
|||d
f d t
|||df t
|||df d f< qZ|||dddf | |ddt
|||df t
|||d
f d |||df f< |||dddf | |ddt
|||df t
|||d
f d |||df f< |||dddf | |dd|||df t
|||df t
|||df d f< |||dddf | |dd|||d
f t
|||df t
|||df d f< qZqL| S )aG  Draw N rectangles on a batch of image tensors.

    Args:
        image: is tensor of BxCxHxW.
        rectangle: represents number of rectangles to draw in BxNx4
            N is the number of boxes to draw per batch index[x1, y1, x2, y2]
            4 is in (top_left.x, top_left.y, bot_right.x, bot_right.y).
        color: a size 1, size 3, BxNx1, or BxNx3 tensor.
            If C is 3, and color is 1 channel it will be broadcasted.
        fill: is a flag used to fill the boxes with color if True.

    Returns:
        This operation modifies image inplace but also returns the drawn tensor for
        convenience with same shape the of the input BxCxHxW.

    Example:
        >>> img = torch.rand(2, 3, 10, 12)
        >>> rect = torch.tensor([[[0, 0, 4, 4]], [[4, 4, 10, 10]]])
        >>> out = draw_rectangle(img, rect)
    z-Image batch and rectangle batch must be equal   z'Number of points in rectangle must be 4Nr   r   r   g        Fr   )shapeAssertionErrorr$   cloner!   clampZtensorexpandr   r&   int)r	   r.   r   r/   batchchwZ
batch_rectZnum_rectangleZ
num_pointsbnZcolor_channelsr   r   r   draw_rectangle   sT    BB&&BBBJr=   )polygonr9   r:   r   c              	   C   s  | j }t| ddddf | ddddf sRtj| | dddddf fdd} | ddddf | ddddf  }}| ddddf | ddddf  }}tj|| j|d}|| || d	  | |}	|ddddf |ddddf  |	ddddf  |ddddf  }
|ddddf |ddddf k|ddddf |ddddf k}||ddddf |ddddf k|ddddf |ddddf kO }|
 }||| < |
 }d|| < |j	ddj
}|jddj
}||fS )
a  Gets the left and right edges of a polygon for each y-coordinate y \in [0, h)
    Args:
        polygons: represents polygons to draw in BxNx2
            N is the number of points
            2 is (x, y).
        h: bottom most coordinate (top coordinate is assumed to be 0)
        w: right most coordinate (left coordinate is assumed to be 0)
    Returns:
        The left and right edges of the polygon of shape (B,B).
    .r   Nr   r   )Zdimr    dtypeg-q=)rA   r!   Zallclosecataranger    r4   logical_andr3   r#   valuesr%   )r>   r9   r:   rA   Zx_startZy_startZx_endZy_endZysZdxxsZvalid_edgesZx_left_edgesZx_right_edgesx_leftx_rightr   r   r   _get_convex_edges   s"    ($&&HJN

rI   )polygonsr   c              	   C   s   t | t t| t d }}tj||d| d j| d jd}t| D ]B\}}t ||k r|t||dd |t | dfn|||< qB|S )a  Converts a List of variable length polygons into a fixed size tensor.

    Works by repeating the last element in the tensor.
    Args:
        polygon: List of variable length polygons of shape [N_1 x 2, N_2 x 2, ..., N_B x 2].
                    B is the batch size,
                    N_i is the number of points,
                    2 is (x, y).
    Returns:
        A fixed size tensor of shape (B, N, 2) where N = max_i(N_i)
    )keyr   r   )rA   r    r   N)	r   r%   r!   zerosrA   r    	enumeraterB   r5   )rJ   r   NZbatched_polygonsr;   pr   r   r   _batch_polygons   s
     <rP   )imagesrJ   colorsr   c                 C   sf  t | g d g | j| jR \}}}}}t|tr<t|}g |j|j|jR \}}	}
}}t|jdkrx|||}g |j|jR \}}	}t	|
dkd t	||  ko|kn  d t	||  ko|kn  d t
|||\}}tj|||dddddf }||d	dddf k||d	dddf k@ }|dddf  |  |dddf |d
   } | S )a  Draws convex polygons on a batch of image tensors.

    Args:
        images: is tensor of BxCxHxW.
        polygons: represents polygons as points, either BxNx2 or List of variable length polygons.
            N is the number of points.
            2 is (x, y).
        color: a B x 3 tensor or 3 tensor with color to fill in.

    Returns:
        This operation modifies image inplace but also returns the drawn tensor for
        convenience with same shape the of the input BxCxHxW.

    Note:
        This function assumes a coordinate system (0, h - 1), (0, w - 1) in the image, with (0, 0) being the center
        of the top-left pixel and (w - 1, h - 1) being the center of the bottom-right coordinate.

    Example:
        >>> img = torch.rand(1, 3, 12, 16)
        >>> poly = torch.tensor([[[4, 4], [12, 4], [12, 8], [4, 8]]])
        >>> color = torch.tensor([[0.5, 0.5, 0.5]])
        >>> out = draw_convex_polygon(img, poly, color)
    )r   r   HWr   r   z/Polygon vertices must be xy, i.e. 2-dimensionalz8Image, polygon, and color must have same batch dimensionz/Image, polygon, and color must have same devicer@   N.).NN)r   r1   r    
isinstancer   rP   rA   r   r5   r   rI   r!   rC   )rQ   rJ   rR   Zb_iZc_iZh_iZw_ir    Zb_p_ZxyZdevice_pZdtype_pZb_cZdevice_crG   rH   wsZfill_regionr   r   r   draw_convex_polygon  s     
",.rX   )NN)typingr   r   r   r   r!   r   Zkornia.testingr   r   r6   r   r-   boolr=   rI   rP   rX   r   r   r   r   <module>   s    n M)