C ++ distance algorithms with Opencv

2

Hello, I have this code in c ++.

Its only entry is a totally white image with a black dot of a pixel in the center ~ (300x300), the image is 600x600.png located in a folder img /

The problem is that I try to make the CDA 3x3 link based on the first pseudocodigo, but the result is more attached to the chessboard, despite having and modifying with variables d1 and d2, with values 3 and 4 respectively.

In chessboard it is of d1 = 1 and d2 = 1, although a white box is shown in the center, in a 100x100 image it can be better appreciated a minimum change between both sets of modified values (d1, d2). Note if I am totally attached to the pseudocode, I have memory access errors that are not accessible or without reference, that is why it does not start from 1 to i less than Y, etc. in the 'for'.

I have the theory that it is the type of data that does not allow me to make certain comparisons, I have tried with Vec3i, int, char, Vec3b I have made so many attempts but the results vary up to show surreal images, this code is the one that It has given me "better" results.

Beforehand, Thank you!

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <math.h>

using namespace std;
using namespace cv;

int main(int argc, char *argv[]){

Mat I = imread("img/6x6.png", CV_LOAD_IMAGE_COLOR);
if(I.empty()){return -1;}int X = I.rows;int Y = I.cols;

///Chamfer 3x3//////////////////////////////////////////////////////////////////////////////////////////////////////
uchar d1=3; uchar d2=4;
Mat d(X, Y, CV_8UC1);//Mat m(rows, cols)
for(int i = 1; i < Y-1; i++){
    for(int j = 1; j < X-1; j++){
        d.at<uchar>(i, j) = 255;
    }
}
for(int i = 1; i < Y-1; i++){
    for(int j = 1; j < X-1; j++){
        if(I.at<uchar>(i-1,j) != I.at<uchar>(i,j) || I.at<uchar>(i+1,j) != I.at<uchar>(i,j)||
           I.at<uchar>(i,j-1) != I.at<uchar>(i,j) || I.at<uchar>(i,j+1) != I.at<uchar>(i,j)){
            d.at<uchar>(i, j) = 0;
        }
    }
}
for(int i = 1; i < Y-1; i++){
    for(int j = 1; j < X-1; j++){
            if(d.at<uchar>(i-1,j-1)+d2<d.at<uchar>(i, j)){d.at<uchar>(i, j) = d.at<uchar>(i-1, j-1)+d2;}
            if(d.at<uchar>(i,j-1)+d1<d.at<uchar>(i, j)){d.at<uchar>(i, j) = d.at<uchar>(i, j-1)+d1;}
            if(d.at<uchar>(i+1, j-1)+d2<d.at<uchar>(i, j)){d.at<uchar>(i, j) = d.at<uchar>(i+1, j-1)+d2;}
            if(d.at<uchar>(i-1, j)+d1<d.at<uchar>(i, j)){d.at<uchar>(i, j) = d.at<uchar>(i-1, j)+d1;}
    }
}
for(int i = Y-1; i > 1; i--){
    for(int j = X-1; j > 1; j--){
        if(d.at<uchar>(i+1, j)+d1<d.at<uchar>(i, j)){d.at<uchar>(i, j) = d.at<uchar>(i+1, j)+d1;}
        if(d.at<uchar>(i-1, j+1)+d2<d.at<uchar>(i, j)){d.at<uchar>(i, j) = d.at<uchar>(i-1, j+1)+d2;}
        if(d.at<uchar>(i, j+1)+d1<d.at<uchar>(i, j)){d.at<uchar>(i, j) = d.at<uchar>(i, j+1)+d1;}
        if(d.at<uchar>(i+1, j+1)+d2<d.at<uchar>(i, j)){d.at<uchar>(i, j) = d.at<uchar>(i+1, j+1)+d2;}
    }
}
for(int i = Y-1; i > 1; i--){
    for(int j = X-1; j > 1; j--){
        if(I.at<uchar>(i,j)==0){d.at<uchar>(i, j)=-d.at<uchar>(i, j);}
    }
}
///Chamfer 3x3//////////////////////////////////////////////////////////////////////////////////////////////////////

imshow("Input", I);
imshow("3x3", d);
waitKey(0);
return 0;
}
    
asked by Julio Cesar Flores Rodríguez 07.02.2018 в 17:21
source

1 answer

0

I did not set out to analyze the problem in its entirety, but it is in the back X and Y.

for(int y = 1; y < Y-1; y++){
    for(int x = 1; x < X-1; x++){
        d.at<uchar>(x, y) = 255;
    }
}

for(int y = 1; y < Y-1; y++){
    for(int x = 1; x < X-1; x++){
        if(I.at<uchar>(x-1,y) != I.at<uchar>(x,y) || I.at<uchar>(x+1,y) != I.at<uchar>(x,y)||
           I.at<uchar>(x,y-1) != I.at<uchar>(x,y) || I.at<uchar>(x,y+1) != I.at<uchar>(x,y)){
            d.at<uchar>(x, y) = 0;
        }
    }
}
for(int y = 1; y < Y-1; y++){
    for(int x = 1; x < X-1; x++){
            if(d.at<uchar>(x-1,y-1)+d2<d.at<uchar>(x, y)){d.at<uchar>(x, y) = d.at<uchar>(x-1, y-1)+d2;}
            if(d.at<uchar>(x,y-1)+d1<d.at<uchar>(x, y)){d.at<uchar>(x, y) = d.at<uchar>(x, y-1)+d1;}
            if(d.at<uchar>(x+1, y-1)+d2<d.at<uchar>(x, y)){d.at<uchar>(x, y) = d.at<uchar>(x+1, y-1)+d2;}
            if(d.at<uchar>(x-1, y)+d1<d.at<uchar>(x, y)){d.at<uchar>(x, y) = d.at<uchar>(x-1, y)+d1;}
    }
}

for(int y = Y-1; y > 1; y--){
    for(int x = X-1; x > 1; x--){
        if(d.at<uchar>(x+1, y)+d1<d.at<uchar>(x, y)){d.at<uchar>(x, y) = d.at<uchar>(x+1, y)+d1;}
        if(d.at<uchar>(x-1, y+1)+d2<d.at<uchar>(x, y)){d.at<uchar>(x, y) = d.at<uchar>(x-1, y+1)+d2;}
        if(d.at<uchar>(x, y+1)+d1<d.at<uchar>(x, y)){d.at<uchar>(x, y) = d.at<uchar>(x, y+1)+d1;}
        if(d.at<uchar>(x+1, y+1)+d2<d.at<uchar>(x, y)){d.at<uchar>(x, y) = d.at<uchar>(x+1, y+1)+d2;}
    }
}
for(int y = Y-1; y > 1; y--){
    for(int x = X-1; x > 1; x--){
        if(I.at<uchar>(x,y)==0){d.at<uchar>(x, y)=-d.at<uchar>(x, y);}
    }
}

Compile, and it gives me more logical results as it appears in the document that you passed.

EDIT: To respond to your comment in a clearer way, I show you this refactored code (which is your 2nd for)

for(int y = 1; y < Y-1; y++){
    for(int x = 1; x < X-1; x++){
            uchar& center = d.at<uchar>(x, y);

            // Checkeo pixel IZQUIERDA, ARRIBA
            uchar& leftTop = d.at<uchar>(x-1,y-1);
            if(leftTop+d2 < center) {
                center = leftTop + d2;
            }

            // Checkeo pixel ARRIBA
            uchar& top = d.at<uchar>(x,y-1);
            if(top + d1 < center) {
                center = top + d1;
            }

            // Checkeo pixel ARRIBA DERECHA
            uchar& rightTop = d.at<uchar>(x+1, y-1);
            if(rightTop + d2 < center) {
                center = rightTop + d2;
            }

            // Checkeo pixel IZQUIERDA
            uchar& left = d.at<uchar>(x-1, y);
            if(left + d1 < center) {
                center = left + d1;
            }
    }
}

Check, that the checks are made on pixels that you already iterated.

Graphical example of the iterations

  

Blue: the pixel you're iterating

     

Green: the pixels you've already iterated

     

C: The pixels you are looking at when iterating

     

Red: Impact

     

White: Pixels you have not iterated yet

Iteracion first X and then Y

Iteration first And then X

Writing outside the limits of the image

There is another problem, that you have it in all the fors when using x and y. Anyway, the code above is repaired, but I'll tell you anyway.

Analyzing this code:

for(int i = 1; i < Y-1; i++){
    for(int j = 1; j < X-1; j++){
        d.at<uchar>(i, j) = 255;
    }
}

You use the variable i for x, but you iterate from 1 to Y (Height) . And the same with the variable j . For that reason, if the image is not of the same width and height, you will be writing outside the limits of the image. Most likely, OpenCV is reporting an exception.

I hope it helps you!

    
answered by 09.02.2018 в 05:54