OpenCV / C++ - редактировать все изолированные пиксели
У меня есть изображение в градациях серого, которое содержит только черный и белый. Из-за шума есть отдельные черные пиксели, от которых я бы хотел избавиться. Я знаю, что открытие и закрытие может быть решением, но я чувствую, что они не являются оптимальными для моего имиджа. Итак, я написал это:
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;
}
}
}
Предполагается, что он пробежит по моему изображению и проверит, является ли пиксель черным, а его окрестности белым. Если это так, пиксель также должен быть превращен в белый. Я запустил это на тестовом изображении, которое было создано этим матом:
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);
Когда я запустил код, ничего не произошло, появилось только оригинальное изображение...
Когда я запустил более простую версию кода, она работала, поэтому синтаксис должен быть правильным:
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;
}
}
}
Кто-нибудь находит мою ошибку в этом?
1 ответ
Процедура в основном правильная, но вы создаете Mat
из float
и вы получаете доступ к нему как char
, Вам нужно, чтобы тип был таким же.
Также ваши итерационные диапазоны должны быть зафиксированы. Вы также можете проверить 8-соединение, иначе ваше изображение с центральным пикселем, установленным в 0, не будет работать должным образом
Помните также, что char
диапазон [-128, +127], поэтому он никогда не будет сравниваться равным 255.
Вот рабочий пример. я использовал uchar
так как это тип, который вам, вероятно, нужен, так как вы работаете с изображением в градациях серого:
#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;
}