O objetivo desta atividade é manipular os pixels de uma imagem utilizando a biblioteca OpenCV, de tal forma que uma imagem seja processada para ser exibido o seu negativo.

Introdução

O negativo, visto em diversas plataformas de edição de imagem, é amplamente utilizado quando se deseja trabalhar em cima de uma figura, modificando-a para, até mesmo, facilidade de análise de detalhes que não seriam vistos em imagens originais. Abaixo podemos ver como seria o tão famoso "negativo":

320
Figura 1. Isadora Renascentista (Original em escala de cinza)
320
Figura 2. Isadora Renascentista (Negativo)

Código no OpenCV

Para mostrar como foi possível obter o negativo da imagem por meio da biblioteca OpenCV, abaixo podemos observar o código que será melhor implementado e explicado em breve.

Listagem 1. negativo.cpp
#include <iostream>
#include <opencv2/highgui.hpp>

using namespace cv;
using namespace std;

int main(int, char**){
  Mat image;
  Vec3b val;

  image= imread("pp.png",CV_LOAD_IMAGE_GRAYSCALE);
  if(!image.data)
    cout << "nao abriu pp.png" << endl;
  namedWindow("janela",WINDOW_AUTOSIZE);


  for(int i=0; i< image.rows; i++){
    for(int j=0; j< image.cols; j++){
      image.at<uchar>(i,j)=255-image.at<uchar>(i,j);
    }
  }

	imwrite("negativo.png", image);
  imshow("janela", image);
  waitKey();
  return 0;
}

Pode-se notar que a implementação da funcionalidade é feita através da realização do cálculo: 255 - valor do pixel. Isso se deve à representação de cor dos pixels, que são valores que variam de 0 a 255, sendo 0 a cor preta, e 255 a cor branca. Dessa forma, quanto maior for o valor do pixel, menor será o resultado do cálculo implementado. E isso provoca o efeito de negativo, onde tonalidades claras tornam-se escuras após o processamento, e tons escuros tornam-se claros. Outra forma de realizar isso é através da operação not nos valores de cada pixel.

Desenvolvimento da atividade

A atividade em questão requer a realização o negativo de uma imagem, porém, com a interação do usuário que irá informar em que pontos o mesmo deseja ter sua imagem negativada. Dessa forma, podemos realizar a implementação de um programa que segue o fluxograma mostrado a seguir:

128
Figura 3. Fluxograma a ser implementado

Código no OpenCV

O código utilizado encontra-se abaixo, bem como comentários feitos no próprio código explicando todos os passos.

Listagem 2. negativo_pontos.cpp
#include <iostream>
#include <opencv2/highgui.hpp>

using namespace cv;
using namespace std;

int main(int, char**){
	Mat image;
	Vec3b val;

//carregando a imagem

	image= imread("pp.png",CV_LOAD_IMAGE_GRAYSCALE);
	if(!image.data){
		cout << "nao abriu pp.png" << endl;
		return 0;
	}

//declarando variáveis para inserção dos pontos pelo usuário

	int x1, y1, x2, y2;

//atribuindo valores às variáveis, através do "Do-while"

	cout << "O tamanho da imagem é: " << image.size().height << "/"<< image.size().width << " Escreva pontos dentro desse limite."<< endl;

	do{
		cout << "digite o primeiro ponto (x):" << endl;
		cin >> x1;
		if(x1 >= image.rows || x1 < 0)
			cout << "Número Inválido :). Insira Novamente." << endl;
	}
	while(x1 >=image.rows);

	do{
		cout << "digite o primeiro ponto (y):" << endl;
		cin >> y1;
		if(y1 >= image.cols || y1 < 0)
			cout << "Número Inválido :). Insira Novamente." << endl;
	}
	while(y1 >=image.cols);

	do{
		cout << "digite o segundo ponto (x):" << endl;
		cin >> x2;
		if(x2 >= image.rows || x2 < 0)
			cout << "Número Inválido :). Insira Novamente." << endl;
	}
	while(x2 >=image.rows);

	do{
		cout << "digite o segundo ponto (y):" << endl;
		cin >> y2;
		if(y2 >= image.cols || y2 < 0)
			cout << "Número Inválido :). Insira Novamente." << endl;
	}
	while(y2 >=image.cols);

//aqui utilizou-se um "for" para fazer a iteração e,
//do ponto inicial informado pelo usuário, até o ponto
//final, ele irá aplicar o negativo.

	for(int i=x1; i<x2; i++){
		for(int j=y1; j<y2; j++){
			image.at<uchar>(i,j)=255-image.at<uchar>(i,j); //nesta linha ocorre a aplicação do negativo.
								       //"255" menos o valor do pixel alocado.
		}
	}

imwrite("points.png",image);
imshow("saida", image);
waitKey();
return 0;
}

Resultados

Com o uso deste programa, a imagem anterior de Isadora fica assim:

320
Figura 4. Isadora Renascentista (Região negativa)

Os pontos utilizados foram:

digite o primeiro ponto (x): 100

digite o primeiro ponto (y): 100

digite o segundo ponto (x): 300

digite o segundo ponto (y): 500

Dessa forma, podemos observar que a implementação de transformações espaciais em uma imagem fazendo o uso da biblioteca OpenCV é bastante prática, sendo útil para diversas aplicações.