OpenCV - remove “white” artifacts from the image and pick a curve

I have an image where I need to remove “white” artifacts that do not represent the detected curve. I want to keep white pixels that represent the curve, but remove pixel outliers that are far from the curve. After removing the artifacts, I would like to place a smooth curve at the points in the image.

This is my image:

white detected curve

The image is an 8-bit grayscale image with only black and white dots. The white pixels in the “curve” represent the region of interest, and most of them are just one pixel thick. Some white pixels are connected to each other, but not all of them. Some white pixels are dotted. I would like to remove these white pixels, since they do not contribute to the overall shape, because I want to put their smooth curve.

So far, I have been trying to execute dilation, followed by operations erosion, closingand black hat. None of them seem to give me the result that I expect. I also tried iterating over all points of the image, finding bright points, looking in a 3x3 neighborhood around this pixel and setting the value 0if it did not have more than two neighbors that are equal.

What can I apply to achieve the desired result? Also, as soon as I get my final “clean” conclusion, how do I place a smooth curve at points in the image?

+1
source share
1 answer

I do not know how to fit the curve, it would be nice to ask about this in another question.


: , . :

OpenCV -

, , :

#include  "opencv2/opencv.hpp"
#include <stdio.h>
#include <iostream>
#include <vector>

using namespace cv;
using namespace std;

- , , , 5 ... , .

void removePepperNoise(Mat &mask)
{
// For simplicity, ignore the top & bottom row border.
for (int y=2; y<mask.rows-2; y++) {
    // Get access to each of the 5 rows near this pixel.
    uchar *pThis = mask.ptr(y);
    uchar *pUp1 = mask.ptr(y-1);
    uchar *pUp2 = mask.ptr(y-2);
    uchar *pDown1 = mask.ptr(y+1);
    uchar *pDown2 = mask.ptr(y+2);

    // For simplicity, ignore the left & right row border.
    pThis += 2;
    pUp1 += 2;
    pUp2 += 2;
    pDown1 += 2;
    pDown2 += 2;
    for (int x=2; x<mask.cols-2; x++) {
        uchar v = *pThis;   // Get the current pixel value (either 0 or 255).
        // If the current pixel is black, but all the pixels on the 2-pixel-radius-border are white
        // (ie: it is a small island of black pixels, surrounded by white), then delete that island.
        if (v == 0) {
            bool allAbove = *(pUp2 - 2) && *(pUp2 - 1) && *(pUp2) && *(pUp2 + 1) && *(pUp2 + 2);
            bool allLeft = *(pUp1 - 2) && *(pThis - 2) && *(pDown1 - 2);
            bool allBelow = *(pDown2 - 2) && *(pDown2 - 1) && *(pDown2) && *(pDown2 + 1) && *(pDown2 + 2);
            bool allRight = *(pUp1 + 2) && *(pThis + 2) && *(pDown1 + 2);
            bool surroundings = allAbove && allLeft && allBelow && allRight;
            if (surroundings == true) {
                // Fill the whole 5x5 block as white. Since we know the 5x5 borders
                // are already white, just need to fill the 3x3 inner region.
                *(pUp1 - 1) = 255;
                *(pUp1 + 0) = 255;
                *(pUp1 + 1) = 255;
                *(pThis - 1) = 255;
                *(pThis + 0) = 255;
                *(pThis + 1) = 255;
                *(pDown1 - 1) = 255;
                *(pDown1 + 0) = 255;
                *(pDown1 + 1) = 255;
            }
            // Since we just covered the whole 5x5 block with white, we know the next 2 pixels
            // won't be black, so skip the next 2 pixels on the right.
            pThis += 2;
            pUp1 += 2;
            pUp2 += 2;
            pDown1 += 2;
            pDown2 += 2;
        }
        // Move to the next pixel.
        pThis++;
        pUp1++;
        pUp2++;
        pDown1++;
        pDown2++;
    }
}
0

Source: https://habr.com/ru/post/1535279/


All Articles