Introdução

Em desenvolvimento…​

Código no OpenCV

O código implementado pode ser visto a seguir:

Listagem 1. pontilhismo.cpp
#include <iostream>
#include <opencv2/opencv.hpp>
#include <fstream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <numeric>
#include <ctime>
#include <cstdlib>

using namespace std;
using namespace cv;

#define STEP 4
#define JITTER 5
#define RAIO 6
#define RAIOCANNY 9
#define CANNY 40
int main(int argc, char** argv){
  vector<int> yrange;
  vector<int> xrange;

  Mat image, frame, points, border;

  int width, height, gray;
  int x, y;

  image= imread(argv[1],CV_LOAD_IMAGE_GRAYSCALE);


  srand(time(0));

  if(!image.data){
	cout << "nao abriu" << argv[1] << endl;
    cout << argv[0] << " imagem.jpg";
    exit(0);
  }

  Canny(image, border,CANNY,3*CANNY);
  imshow("canny", border);
  waitKey(0);


  width=image.size().width;
  height=image.size().height;

  xrange.resize(height/STEP);
  yrange.resize(width/STEP);

  iota(xrange.begin(), xrange.end(), 0);
  iota(yrange.begin(), yrange.end(), 0);

  for(uint i=0; i<xrange.size(); i++){
    xrange[i]= xrange[i]*STEP+STEP/2;
  }

  for(uint i=0; i<yrange.size(); i++){
    yrange[i]= yrange[i]*STEP+STEP/2;
  }

  points = Mat(height, width, CV_8U, Scalar(255));

  random_shuffle(xrange.begin(), xrange.end());

  for(auto i : xrange){
    random_shuffle(yrange.begin(), yrange.end());
    for(auto j : yrange){
      x = i+rand()%(2*JITTER)-JITTER+1;
      y = j+rand()%(2*JITTER)-JITTER+1;

      if(border.at<uchar>(i,j)==255){
        x = i;
        y = j;
        gray = image.at<uchar>(x,y);
        circle(points, cv::Point(y,x), RAIOCANNY, gray, -1,  CV_AA);
      }
      else{
        gray = image.at<uchar>(x,y);
        circle(points, cv::Point(y,x), RAIO, gray, -1,  CV_AA);
      }
    }
  }
  imshow("result", points);
  waitKey(0);
  imwrite("pontos.jpg", points);
  return 0;
}

Resultados

Podemos ver o resultado da aplicação do filtro a seguir:

450
Figura 1. Imagem de entrada
450
Figura 2. Imagem de saída.