I have an grayscale image, which just contains black and white. There are some isolated black pixels due to noise, which I would like to get rid of. I know that opening and closing might be a solution, but I feel like they are not optimal for my image. So I wrote this:
for (int i = 1; i < pixels.rows; ++i) {
for (int j = 1; j < pixels.cols; ++j) {
if ((pixels.at<char>(i, j) == 0) &&
(pixels.at<char>(i - 1, j) == 255) &&
(pixels.at<char>(i, j - 1) == 255) &&
(pixels.at<char>(i + 1, j) == 255) &&
(pixels.at<char>(i, j + 1) == 255)) {
pixels.at<char>(i, j) = 255;
}
}
}
It is supposed to run through my image and check if the pixel is black and his neighborhood is white. If that's the case the pixel should be turned into an white pixel also. I ran this on an test image, which was created by this Mat:
Mat pixels = (Mat_<float>(5, 5) <<
255, 255, 255, 255, 255,
255, 0, 255, 0, 255,
255, 255, 255, 255, 255,
255, 0, 255, 0, 255,
255, 255, 255, 255, 255);
When I ran the code nothing happened, just the original image appeared...
When I ran a simpler version of the code, it worked, so the syntax actually should be correct:
for (int i = 1; i < pixels.rows; ++i) {
for (int j = 1; j < pixels.cols; ++j) {
if ((pixels.at<char>(i, j) == 0)) {
pixels.at<char>(i, j) = 255;
}
}
}
Does anyone find my mistake in this?
The procedure is basically correct, but you're creating a Mat
of float
and you are accessing it as char
. You need the type to be the same.
Also your iteration ranges need to be fixed. You may also want to check 8-connection, otherwise your image with the central pixel set to 0 won't work as expected
Remember also that char
range is [-128, +127], so it will never compare equal to 255.
Here's a working example. I used uchar
since it's the type you probably need since you're working on a grayscale image:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
int main()
{
Mat pixels = (Mat_<uchar>(5, 5) <<
255, 255, 255, 255, 255,
255, 0, 255, 0, 255,
255, 255, 255, 255, 255,
255, 0, 255, 0, 255,
255, 255, 255, 255, 255);
for (int i = 1; i < pixels.rows - 1; ++i) {
for (int j = 1; j < pixels.cols - 1; ++j)
{
if ((pixels.at<uchar>(i, j) == 0) &&
(pixels.at<uchar>(i - 1, j - 1) == 255) && // Top Left
(pixels.at<uchar>(i - 1, j + 0) == 255) && // Top
(pixels.at<uchar>(i - 1, j + 1) == 255) && // Top Right
(pixels.at<uchar>(i + 0, j - 1) == 255) && // Left
(pixels.at<uchar>(i + 0, j + 1) == 255) && // Right
(pixels.at<uchar>(i + 1, j - 1) == 255) && // Bottom Left
(pixels.at<uchar>(i + 1, j + 0) == 255) && // Bottom
(pixels.at<uchar>(i + 1, j + 1) == 255) // Bottom Right
)
{
pixels.at<uchar>(i, j) = 255;
}
}
}
std::cout << pixels;
return 0;
}