1
I wrote code to "skeletonize" figures, that is, to reduce their thicknesses to just one pixel. I had already written the code in Python that worked correctly. However, the same code rewritten to C++, although Compile and run error-free, does not produce the same result as with Python. Follow an excerpt of the code in C++ to see if anyone will help me, thank you.
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int vizinhos(int x, int y, int img[][180]);
int zero_um(int x, int y, int img[][180]);
int multiplica_r1(int x, int y, int img[][180]);
int multiplica_r2(int x, int y, int img[][180]);
int conta_pixels(int img[][180]);
// INÍCIO DA FUNÇÃO PRINCIPAL ******************************************
int main(){
// Lê a imagem original
Mat img;
img = imread("/home/dexter/Público/xis.png", CV_LOAD_IMAGE_GRAYSCALE);
// Binariza a imagem
Mat img_bin;
threshold(img, img_bin, 50, 255, THRESH_BINARY);
// Obtém o negativo da imagem binarizada
int img_bin_neg[180][180];
for (int i=0; i<180; i++) {
for(int j=0; j<180; j++) {
img_bin_neg[i][j] = (255 - img_bin.at<uchar>(i,j)) / 255;
}
}
// EFETUA A ESQUELETONIZAÇÃO **************
int brancos0, brancos1, dif;
brancos0 = conta_pixels(img_bin_neg);
dif = 10;
int flag[180][180];
while (dif > 0) {
// Aplica conjunto de regras 1
for (int i=1; i<179; i++) {
for (int j=1; j<179; j++) {
int B = vizinhos(i,j,img_bin_neg);
bool teste1 = (B >= 2) && (B <= 6);
int A = zero_um(i,j,img_bin_neg);
bool teste2 = (A == 1);
int p2p4p6, p4p6p8 = multiplica_r1(i,j,img_bin_neg);
bool teste3 = (p2p4p6 == 0);
bool teste4 = (p4p6p8 == 0);
if (teste1 * teste2 * teste3 * teste4 == 1) {
flag[i][j] = 1;
}
}
}
for (int i=0; i<180; i++) {
for (int j=0; j<180; j++) {
if (flag[i][j] == 1) { img_bin_neg[i][j] = 0; }
}
}
// Aplica conjunto de regras 2
for (int i=1; i<179; i++) {
for (int j=1; j<179; j++) {
int B = vizinhos(i,j,img_bin_neg);
bool teste1A = (B >= 3) && (B <= 6);
int A = zero_um(i,j,img_bin_neg);
bool teste2A = (A == 1);
int p2p4p8, p2p6p8 = multiplica_r2(i,j,img_bin_neg);
bool teste3A = (p2p4p8 == 0);
bool teste4A = (p2p6p8 == 0);
if (teste1A * teste2A * teste3A * teste4A == 1) {
flag[i][j] = 1;
}
}
}
for (int i=0; i<180; i++) {
for (int j=0; j<180; j++) {
if (flag[i][j] == 1) { img_bin_neg[i][j] = 0; }
}
}
brancos1 = conta_pixels(img_bin_neg);
dif = brancos0 - brancos1;
brancos0 = brancos1;
} // Fim do laço while
// IMAGEM ESQUELETONIZADA
int m_esqueleto[180][180];
for (int i=0; i<180; i++) {
for(int j=0; j<180; j++) {
m_esqueleto[i][j] = 1 - img_bin_neg[i][j];
}
}
Mat esqueletonizada(180, 180, CV_8UC1);
for (int i=0; i<180; i++) {
for (int j=0; j<180; j++) {
esqueletonizada.at<uchar>(i,j) = m_esqueleto[i][j] * 255;
}
}
namedWindow("img esqueletonizada", WINDOW_NORMAL);
imshow("img esqueletonizada", esqueletonizada);
waitKey();
return 0;
}
// FIM DA FUNÇÃO PRINCIPAL *************************
// FUNÇÕES PARA ESQUELETONIZAÇÃO
int vizinhos(int x, int y, int img[][180]){
int B = 0;
for (int j=0; j<3; j++) {
int v = j+y-1;
B += img[x-1][v] + img[x+1][v];
}
B += img[x][y-1] + img[x][y+1];
return B;
}
int zero_um(int x, int y, int img[][180]){
int A = 0;
for (int j=0; j<2; j++) {
int v = j+y-1;
if (img[x-1][v]==0 && img[x-1][v+1]==1) { A += 1; }
if (img[x+1][v]==1 && img[x+1][v+1]==0) { A += 1; }
}
for (int i=0; i<2; i++){
int u = i+x-1;
if (img[u][y+1]==0 && img[u+1][y+1]==1) { A += 1; }
if (img[u][y-1]==1 && img[u+1][y-1]==0) { A += 1; }
}
return A;
}
int multiplica_r1(int x, int y, int img[][180]){
int p2p4p6 = img[x-1][y] * img[x][y+1] * img[x+1][y];
int p4p6p8 = img[x][y+1] * img[x+1][y] * img[x][y-1];
return p2p4p6, p4p6p8;
}
int multiplica_r2(int x, int y, int img[][180]){
int p2p4p8 = img[x-1][y] * img[x][y+1] * img[x][y-1];
int p2p6p8 = img[x-1][y] * img[x+1][y] * img[x][y-1];
return p2p4p8, p2p6p8;
}
int conta_pixels(int img[][180]){
int pixels_brancos = 0;
for (int i=0; i<180; i++){
for (int j=0; j<180; j++){
if (img[i][j] == 1) { pixels_brancos += 1; }
}
}
return pixels_brancos;
}
Hello @Dexter, are you wanting to use the functions of opencv even to do this, or are you trying to do the "skeletonization" in your own way?
– Diego Ferreira
I used opencv only to read and manipulate matrices. By the way, I don’t even know if I needed to import all these libraries.
– Dexter