There are images (straight straight line can be in any direction):

enter image description here enter image description here enter image description here enter image description here

It is necessary to calculate from which side this straight line (conventionally) is located and rotate the image so that it is DOWN. I tried to look for the greatest length, when the pixels go one after the other, but it turns out very slowly, since 4 cycles for each need.

for (int X = 0; X < image.height()/2; X++) { for (int Y = 0; Y < image.width(); Y++) { if (QColor(image.pixel(X,Y)).name()=="#ffffff") { int i = Y+1; int max_buffer; while(QColor(image.pixel(X,i)).name()=="#ffffff") { max_buffer++; i++; } if(max_buffer>max_top) { max_top = max_buffer; } } } } 

This cycle is only for upwards, another 3 for other parties and then to compare which is more, etc. I read that it is possible to implement this method and make it more optimized. UPADETE: The image is already binary (black and white, monochrome)!

    2 answers 2

    If the slice is always parallel to the axes of coordinates, then the scanning line from each direction to count the number of white pixels in the line. For a slice, this number will increase sharply as the line moves, for a round side there will be a curve — a recumbent parabola — a square root. The method is unstable even to a slight slope.

    If the direction of the slice is arbitrary, you can calculate the moments of Hu for the image and estimate the orientation. Its calculation is, for example, in OpenCV.

    Something I didn’t think about the simplest application of moments - to calculate the center of mass of a fragment containing a truncated circle, and to find in which direction the white pixels end closer from this center. It will be perpendicular to the desired slice.

      ll sumx = 0; ll sumy = 0; ll sumv = 0; for (int y = 0; y < image.height(); y++) { for (int x = 0; x < image.width(); x++) { sumx += value[y][x] * x; sumy += value[y][x] * y; sumv += value[y][x]; } } masscenterx = sumx / sumv; masscentery = sumy / sumv; 
    • The idea with the center of the masses is logical. Can you briefly describe how to find it? - Optimus
    • So by definition - add all the value[i][j] * i and value[i][j] * j and divide by the sum of value[i][j] - you get the coordinates. - MBo
    • But this way we get the center of the picture itself, and not the truncated circle, and it can be shifted - Optimus
    • No, white pixels at the expense of a larger value "attract" the center to itself - MBo
    • one
      added pseudocode - MBo

    As I understand it, a straight line in the image can be parallel to one of the sides of the image. In this case, I suggest the following search algorithm:

    1. We get to the edge of the image in the middle of the face (there will be 4 cases - x = 0, y = h / 2; x = w, y = h / 2; x = w / 2, y = 0; x = w / 2, y = h, where w and h are, respectively, the width and height of the image), then for simplicity we analyze for the first case
    2. Moving to the center of the image (in this case, in the direction of increasing x) and looking for a white pixel
    3. When a white pixel is found, we go from 0 to the height of the image by the x white pixel found and count the number of white pixels on this line, remember.

    We repeat in the same way for four faces, the desired flat face corresponds to the one where the found number of white pixels is maximum.

    Image for clarity of the algorithm:

    enter image description here

    I will add that you have a very large overhead on color matching, first converting to QColor , then converting to QString and then comparing strings. I would like to write something like

     QRgb pixel = image.pixel(X, Y); if (qRed(pixel) == 255 && qGreen(pixel) == 255 && qBlue(pixel) == 255) ... 

    ZY I thought a little, in theory, the algorithm is resistant to a slight rotation of the image, but we need to test

    ZYY.Y. There is a second variant of the algorithm, you can calculate the set of distances from the edge of the image to the first white pixel encountered, on which face the difference between these distances will be minimal, that face is the desired one. Which of the two options is more optimal, I can’t guess, I have to test it.

    • Unfortunately, although this is useful advice, it is not the answer to the question posed. Please either transfer it to the comments, or add to another answer, or rephrase the answer so that it is the answer. - Kromster
    • one
      @Kromster had to quickly come up with a fast and seemingly accurate algorithm - Bearded Beaver