Este tutorial é a base da visão computacional apresentada como “Lição 2” da série; há mais lições por vir que abordarão a extensão de construir seus próprios projetos de visão computacional baseados em aprendizado profundo. Você pode encontrar o plano de estudos completo e sumário aqui.
Os principais aprendizados deste artigo:
- Carregar uma Imagem do Disco.
- Obter a ‘Altura’, ‘Largura’ e ‘Profundidade’ da Imagem.
- Encontrar os componentes R, G e B da Imagem.
- Desenhar usando OpenCV.
Carregar uma Imagem do Disco
Antes de realizarmos quaisquer operações ou manipulações de uma imagem, é importante para nós carregar uma imagem de nossa escolha no disco. Realizaremos essa atividade usando OpenCV. Existem duas maneiras pelas quais podemos realizar essa operação de carregamento. Uma maneira é carregar a imagem simplesmente passando o caminho da imagem e o arquivo da imagem para a função “imread” da OpenCV. A outra maneira é passar a imagem por um argumento de linha de comando usando o módulo python argparse.
#Carregando Imagem do disco
import cv2
image = cv2.imread(“C:/Sample_program/example.jpg”)
cv2.imshow(‘Image’, image)
cv2.waitKey(0)
Vamos criar um arquivo chamado Loading_image_from_disk.py no Notepad++. Primeiro, importamos a biblioteca OpenCV, que contém nossas funções de processamento de imagem. Importamos a biblioteca usando a primeira linha de código como cv2. A segunda linha de código é onde lemos nossa imagem usando a função cv2.imread em OpenCV, e passamos o caminho da imagem como parâmetro; o caminho também deve conter o nome do arquivo com sua extensão de formato de imagem .jpg, .jpeg, .png ou .tiff.
sintaxe — // image=cv2.imread(“caminho/para/sua/imagem.jpg”) //
É preciso ter muito cuidado ao especificar o nome da extensão do arquivo. É provável que recebamos o erro abaixo se fornecemos a extensão errada.
ERROR :
c:\Sample_program>python Loading_image_from_disk.py
Traceback (most recent call last):
File “Loading_image_from_disk.py”, line 4, in <module>
cv2.imshow(‘Image’, image)
cv2.error: OpenCV(4.3.0) C:\projects\opencv-python\opencv\modules\highgui\src\window.cpp:376: error: (-215:Assertion failed) size.width>0 && size.height>0 in function ‘cv::imshow’
A terceira linha de código é onde realmente exibimos nossa imagem carregada. O primeiro parâmetro é uma string, ou o “nome” da nossa janela. O segundo parâmetro é o objeto para o qual a imagem foi carregada.
Finalmente, uma chamada para cv2.waitKey pausa a execução do script até pressionarmos uma tecla no teclado. Usar um parâmetro de “0” indica que qualquer pressionamento de tecla despausará a execução. Sinta-se à vontade para executar seu programa sem ter a última linha de código no seu programa para ver a diferença.
#Lendo Imagem do disco usando Argparse
import cv2
import argparse
apr = argparse.ArgumentParser()
apr.add_argument(“-i”, “ — image”, required=True, help=”Path to the image”)
args = vars(apr.parse_args())
image = cv2.imread(args[“image”])
cv2.imshow(‘Image’, image)
cv2.waitKey(0)
Saber ler uma imagem ou arquivo usando um argumento de linha de comando (argparse) é uma habilidade absolutamente necessária.
As duas primeiras linhas de código são para importar bibliotecas necessárias; aqui, importamos OpenCV e Argparse. Isto será repetido ao longo do curso.
Os três seguintes linhas de código lidam com a análise dos argumentos da linha de comando. O único argumento de que precisamos é — image: o caminho para nossa imagem no disco. Por fim, analisamos os argumentos e os armazenamos em um dicionário chamado args.
Vamos dedicar um segundo e discutir rapidamente exatamente o que é o switch — image. O “switch” — image (“switch” é sinônimo de “argumento da linha de comando” e os termos podem ser usados de forma intercambiável) é uma string que especificamos na linha de comando. Esse switch informa ao script Loading_image_from_disk.py onde a imagem que queremos carregar está localizada no disco.
As três últimas linhas de código foram discutidas anteriormente; a função cv2.imread toma args[“image”] como parâmetro, que nada mais é do que a imagem que fornecemos no prompt de comando. cv2.imshow exibe a imagem, que já está armazenada em um objeto de imagem da linha anterior. A última linha pausa a execução do script até pressionarmos uma tecla no teclado.
Uma das principais vantagens de usar um argparse — argumento de linha de comando é que poderemos carregar imagens de diferentes locais de pastas sem precisar alterar o caminho da imagem no nosso programa, passando dinamicamente o caminho da imagem Ex — “C:\CV_Material\image\sample.jpg” no prompt de comando como argumento enquanto executamos nosso programa Python.
c:\Sample_program>python Loading_image_from_disk.py — image C:\CV_Material\session1.JPG
Aqui, estamos executando o Loading_image_from_disk.py arquivo Python a partir do c:\sample_program local, passando o parâmetro “-image” junto com o caminho da imagem C:\CV_Material\session1.JPG.
Obtendo a ‘Altura’, ‘Largura’ e ‘Profundidade’ da Imagem
Uma vez que as imagens são representadas como arrays NumPy, podemos simplesmente usar o atributo .shape para examinar a largura, altura e número de canais.
Ao utilizar o atributo .shape no objeto de imagem que acabamos de carregar, podemos encontrar a altura, largura e profundidade da imagem. Como discutido no aula anterior — 1, a altura e a largura da imagem podem ser verificadas cruzadamente abrindo a imagem no MS Paint. Consulte a aula anterior. Discutiremos sobre a profundidade da imagem nas próximas aulas. A profundidade também é conhecida como canal de uma imagem. As imagens coloridas geralmente têm 3 canais devido à composição RGB em seus pixels e as imagens em escala de cinza têm 1 canal. Isso é algo que discutimos na Aula-1.
#Obtenção da Altura, Largura e Profundidade de uma Imagem
import cv2
import argparse
apr = argparse.ArgumentParser()
apr.add_argument(“-i”, “ — image”, required=True, help=”Path to the image”)
args = vars(apr.parse_args())
# Apenas diferença em relação aos códigos anteriores — atributo shape aplicado no objeto de imagem
print(f’(Height,Width,Depth) of the image is: {image.shape}’)
image = cv2.imread(args[“image”])
cv2.imshow(‘Image’, image)
cv2.waitKey(0)
Saída:
(Altura, Largura, Profundidade) da imagem é: (538, 723, 3)
A única diferença em relação aos códigos anteriores é a instrução de impressão que aplica o atributo shape ao objeto de imagem carregado. f’ é a string formatada F que aceita variáveis dinamicamente e imprime.
f’ write anything here that you want to see in the print statement: {variables, variables, object, object.attribute,}’
Aqui, utilizamos {object.attribute} dentro dos colchetes para o atributo .shape para calcular a altura, largura e profundidade do objeto de imagem.
#Obtendo Altura, Largura e Profundidade separadamente
import cv2
import argparse
apr = argparse.ArgumentParser()
apr.add_argument(“-i”, “ — image”, required=True, help=”Path to the image”)
args = vars(apr.parse_args())
image = cv2.imread(args[“image”])
#Fatiamento de array NumPy para obter a altura, largura e profundidade separadamente
print(“height: %d pixels” % (image.shape[0]))
print(“width: %d pixels” % (image.shape[1]))
print(“depth: %d” % (image.shape[2]))
cv2.imshow(‘Image’, image)
cv2.waitKey(0)
Saída:
largura: 723 pixels
altura: 538 pixels
profundidade: 3
Aqui, em vez de obter (altura, largura e profundidade) juntos como uma tupla, realizamos o fatiamento de array e obtemos a altura, largura e profundidade da imagem individualmente. O índice 0 do array contém a altura da imagem, o índice 1 contém a largura da imagem e o índice 2 contém a profundidade da imagem.
Encontrando os Componentes R, G e B da Imagem
Saída:
O valor do componente Azul Verde Vermelho da imagem na posição (321, 308) é: (238, 242, 253)
Observe como o valor y é passado antes do valor x — essa sintaxe pode parecer contra-intuitiva no início, mas é consistente com a forma como acessamos valores em uma matriz: primeiro especificamos o número da linha, depois o número da coluna. A partir daí, recebemos uma tupla representando os componentes Azul, Verde e Vermelho da imagem.
Também podemos alterar a cor de um pixel em uma posição específica invertendo a operação.
#Encontrando R, B, G da Imagem na posição (x, y)
import cv2
import argparse
apr = argparse.ArgumentParser()
apr.add_argument(“-i”, “ — image”, required=True, help=”Path to the image”)
args = vars(apr.parse_args())
image = cv2.imread(args[“image”])
#Receber o valor de coordenada do pixel como [y, x] do usuário, para o qual os valores RGB devem ser calculados
[y,x] = list(int(x.strip()) for x in input().split(‘,’))
#Extrair os valores (Azul, Verde, Vermelho) do pixel de coordenada recebida
(b,g,r) = image[y,x]
print(f’The Blue Green Red component value of the image at position {(y,x)} is: {(b,g,r)}’)
cv2.imshow(‘Image’, image)
cv2.waitKey(0)
(b,g,r) = image[y,x] para image[y,x] = (b,g,r)
Aqui, atribuímos a cor em (BGR) à coordenada do pixel da imagem. Vamos tentar atribuindo a cor vermelha ao pixel na posição (321,308) e validamos o mesmo imprimindo o BGR do pixel na posição dada.
# Revertendo a Operação para atribuir valor RGB ao pixel da nossa escolha
import cv2
import argparse
apr = argparse.ArgumentParser()
apr.add_argument(“-i”, “ — image”, required=True, help=”Path to the image”)
args = vars(apr.parse_args())
image = cv2.imread(args[“image”])
# Receber o valor da coordenada do pixel como [y,x] do usuário, para o qual os valores RGB devem ser calculados
[y,x] = list(int(x.strip()) for x in input().split(‘,’))
# Extrair os valores (Azul, Verde, Vermelho) da coordenada do pixel recebida
image[y,x] = (0,0,255)
(b,g,r) = image[y,x]
print(f’The Blue Green Red component value of the image at position {(y,x)} is: {(b,g,r)}’)
cv2.imshow(‘Image’, image)
cv2.waitKey(0)
Saída:
Os valores das componentes Azul, Verde e Vermelho da imagem na posição (321, 308) são (0, 0, 255)
No código acima, recebemos a coordenada do pixel através do prompt de comando inserindo o valor como mostrado na Figura 2.6 abaixo e atribuímos a cor vermelha à coordenada do pixel atribuindo (0,0,255) ou seja, (Azul, Verde, Vermelho) e validamos o mesmo imprimindo a coordenada do pixel de entrada.
Desenho Usando OpenCV
Vamos aprender a desenhar diferentes formas como retângulos, quadrados e círculos usando OpenCV, desenhando círculos para mascarar meus olhos, retângulos para mascarar meus lábios e retângulos para mascarar o peixe manta-ray ao meu lado.
A saída deve ser assim:
Esta foto está mascarada com formas usando o MS Paint; tentaremos fazer o mesmo usando OpenCV, desenhando círculos em torno dos meus olhos e retângulos para mascarar meus lábios e o peixe manta-ray ao meu lado.
Usamos o método cv2.rectangle para desenhar um retângulo e o método cv2.circle para desenhar um círculo no OpenCV.
cv2.rectangle(image, (x1, y1), (x2, y2), (Blue, Green, Red), Thickness)
O método cv2.rectangle recebe uma imagem como seu primeiro argumento, na qual queremos desenhar nosso retângulo. Queremos desenhar na imagem carregada, então a passamos para o método. O segundo argumento é a posição inicial (x1, y1) do nosso retângulo — aqui, estamos começando nosso retângulo nos pontos (156 e 340). Em seguida, devemos fornecer um ponto final (x2, y2) para o retângulo. Decidimos terminar nosso retângulo em (360, 450). O argumento seguinte é a cor do retângulo que queremos desenhar; neste caso, estamos passando a cor preta no formato BGR, ou seja, (0,0,0). Por fim, o último argumento que passamos é a espessura da linha. Damos -1 para desenhar formas sólidas, conforme visto na Fig 2.6.
Da mesma forma, usamos o método cv2.circle para desenhar o círculo.
cv2.circle(image, (x, y), r, (Blue, Green, Red), Thickness)
O método cv2.circle recebe uma imagem como seu primeiro argumento, na qual queremos desenhar nosso retângulo. Queremos desenhar na imagem carregada, então a passamos para o método. O segundo argumento é a posição central (x, y) do nosso círculo — aqui, tomamos nosso círculo no ponto (343, 243). O argumento seguinte é o raio do círculo que queremos desenhar. O argumento seguinte é a cor do círculo; neste caso, estamos passando a cor vermelha no formato BGR, ou seja, (0,0,255). Por fim, o último argumento que passamos é a espessura da linha. Damos -1 para desenhar formas sólidas, conforme visto na Fig 2.6.
Ok! Conhecendo tudo isso, vamos tentar realizar o que começamos. Para desenhar as formas na imagem, precisamos identificar as coordenadas de início e fim (x, y) da região de máscara para passá-las ao método correspondente.
Como?
Vamos recorrer ao MS Paint mais uma vez. Ao posicionar o cursor sobre uma das coordenadas (canto superior esquerdo) ou (canto inferior direito) da região a ser mascarada, as coordenadas são mostradas na parte destacada do MS Paint, conforme mostrado na Figura 2.7.
Da mesma forma, coletaremos todas as coordenadas (x1, y1) (x2, y2) para todas as regiões de máscara, conforme mostrado na Figura 2.8.
#Desenho usando OpenCV para mascarar olhos, boca e objeto próximo
import cv2
import argparse
apr = argparse.ArgumentParser()
apr.add_argument(“-i”, “ — image”, required=True, help=”Path to the image”)
args = vars(apr.parse_args())
image = cv2.imread(args[“image”])
cv2.rectangle(image, (415, 168), (471, 191), (0, 0, 255), -1)
cv2.circle(image, (425, 150), 15, (0, 0, 255), -1)
cv2.circle(image, (457, 154), 15, (0, 0, 255), -1)
cv2.rectangle(image, (156, 340), (360, 450), (0, 0, 0), -1)
#Mostrar a imagem de saída
cv2.imshow(“Output drawing “, image)
cv2.waitKey(0)
Resultado:

Source:
https://dzone.com/articles/computer-vision-tutorial-2-image-basics