OpenCV / C++ - 编辑所有孤立的像素
OpenCV / C++ - Edit all isolated pixels
我有一个灰度图像,其中只包含黑色和白色。由于噪声,有一些孤立的黑色像素,我想将其去除。我知道打开和关闭可能是一个解决方案,但我觉得它们不是我形象的最佳选择。所以我写了这个:
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 创建的测试图像:
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;
}
}
}
有人发现我的错误吗?
该过程基本上是正确的,但是您正在创建一个 float
的 Mat
,并且您正在以 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;
}
我有一个灰度图像,其中只包含黑色和白色。由于噪声,有一些孤立的黑色像素,我想将其去除。我知道打开和关闭可能是一个解决方案,但我觉得它们不是我形象的最佳选择。所以我写了这个:
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 创建的测试图像:
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;
}
}
}
有人发现我的错误吗?
该过程基本上是正确的,但是您正在创建一个 float
的 Mat
,并且您正在以 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;
}