A Visão Computacional, como você sabe (ou mesmo se não conhece), é uma ferramenta muito poderosa com imensas possibilidades. Então, quando planejei preparar uma história em quadrinhos da vida de um amigo na faculdade, logo percebi que precisava de algo que reduzisse meus esforços de pintá-lo, mas que mantivesse a qualidade, e encontrei a seguinte solução.

Vamos ver o resultado primeiro -

Desenho de uma imagem usando OpenCV (python)Imagem original

 

Desenho de uma imagem usando OpenCV (python) 1



Versão cartoon

1

Bordas obtidas a partir da imagem (resultado do Limiar Adaptativo)

Vamos ver o código:

class Cartoonizer:  
  
      
    
    def __init__(self):  
        pass
  
    def render(self, img_rgb):  
        img_rgb = cv2.imread(img_rgb)  
        img_rgb = cv2.resize(img_rgb, (1366,768))  
        numDownSamples = 2  
        numBilateralFilters = 50
        img_color = img_rgb  
        for _ in range(numDownSamples):  
            img_color = cv2.pyrDown(img_color)  
      
      for _ in range(numBilateralFilters):  
            img_color = cv2.bilateralFilter(img_color, 9, 9, 7
      
        for _ in range(numDownSamples):  
            img_color = cv2.pyrUp(img_color)  
      
      img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2GRAY)  
        img_blur = cv2.medianBlur(img_gray, 3
      
      img_edge = cv2.adaptiveThreshold(img_blur, 255
                                        cv2.ADAPTIVE_THRESH_MEAN_C,  
                                        cv2.THRESH_BINARY, 9, 2
      
      (x,y,z) = img_color.shape  
        img_edge = cv2.resize(img_edge,(y,x))  
        img_edge = cv2.cvtColor(img_edge, cv2.COLOR_GRAY2RGB)  
        cv2.imwrite("edge.png",img_edge)  
      
      
        return cv2.bitwise_and(img_color, img_edge)  
  
tmp_canvas = Cartoonizer()  
  
file_name = "Screenshot.png"
res = tmp_canvas.render(file_name)  
  
cv2.imwrite("Cartoon version.jpg", res)  
cv2.imshow("Cartoon version", res)  
cv2.waitKey(0
cv2.destroyAllWindows()  

Explicação:

Basicamente, vamos usar uma série de filtros e conversões de imagens.

  • Primeiro, reduzimos a escala da imagem e, em seguida, aplicamos o filtro bilateral para obter um sabor de desenho animado. Então, novamente aumentamos a imagem.
  • O próximo passo é obter uma versão desfocada da imagem original. Agora, não queremos que as cores interfiram neste processo. Queremos apenas a indefinição das fronteiras. Para isso, primeiro convertemos a imagem em escala de cinza e depois aplicamos o filtro de desfoque de mídia.
  • A próxima etapa é identificar as bordas na imagem e, em seguida, adicioná-las às imagens modificadas anteriormente para obter um efeito de caneta de esboço. Para este primeiro, estamos usando o limite adaptativo. Você também pode experimentar outros tipos de técnicas de limite. Porque a visão computacional é sobre experimentação. Na etapa 5, compilamos as imagens finais obtidas nas etapas anteriores.

Implementação mais simples -

import cv2 
import numpy as np 
img = cv2.imread("koala.jpeg") 
   
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 
gray = cv2.medianBlur(gray, 5) 
edges = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C,  
                                         cv2.THRESH_BINARY, 9, 9) 
   
color = cv2.bilateralFilter(img, 9, 250, 250) 
cartoon = cv2.bitwise_and(color, color, mask=edges) 
   
   
cv2.imshow("Image", img) 
cv2.imshow("edges", edges) 
cv2.imshow("Cartoon", cartoon) 
cv2.waitKey(0) 
cv2.destroyAllWindows() 

O que você pode fazer?
Experimentar! Tente alterar as etapas de amostragem abaixo, ou o número de filtros bilaterais aplicados, ou mesmo o tamanho do filtro, ou a técnica de limite para obter as bordas. Agora, uma coisa para se manter em mente. Este processo é geral e não dará o melhor resultado para imagens diferentes. É por isso que você deve experimentar diferentes valores para ter uma ideia de todo o processo.

Isso é tudo do meu lado! Auf Wiedersehen!

Sobre o autor:

Vishwesh Shrimali é um estudante de graduação em Engenharia Mecânica na BITS Pilani. Ele atende visha todos os requisitos não ensinados em seu ramo - hacker de chapéu branco, operador de segurança de rede e um ex-Programador Competitivo. Como um crente firme no poder do Python, sua maior parte do trabalho tem sido na mesma linguagem. Sempre que ele fica um tempo longe da programação, das aulas, assistindo CSI Cyber, ele sai para uma longa caminhada e toca violão em silêncio. Seu lema de vida é - “Aproveite sua vida, porque vale a pena desfrutar!”

Se você também deseja mostrar o seu blog aqui, consulte  GBlog para escrever um blog convidado no GeeksforGeeks.