Функция заливки не работает

Я хочу сделать заливку для 2D-изображений, но продолжаю получать те же результаты.

Программа довольно проста. Он считывает двухмерное изображение из текстового файла, содержащего 0 и 1, и применяет вариант глубины первого алгоритма заливки:

void floodFill (int u, int v, int label,Image &img, ImageLabels &imgL)
{

struct Point { int x; int y; int l;};

Point p = {0 , 0 , 1};

u = p.x;
v = p.y;
label = p.l;

vector <Point> stack;
stack.push_back(p);

while (!stack.empty())
{
Point p = stack.back();
stack.pop_back();Point one = {(p.x+1), p.y, label};
Point two = {p.x,(p.y+1), label};
Point three = {p.x,(p.y-1), label};
Point four = {(p.x-1),p.y, label};
if ((p.x>=0) && (p.x<img.size()) && (p.y>=0) && (p.y<img[0].size()) && img[p.x][p.y]==1)
{
stack.push_back(one);
stack.push_back(two);
stack.push_back(three);
stack.push_back(four);
img[p.x][p.y] = label;
}
}
}

Вот код маркировки изображения:

void imageLabeling(Image &img, ImageLabels &imgL)
{
long int numLines=img.size();
long int numCols=img[0].size();

int u=0;
int v=0;
int label=1;

imgL.resize(numLines);
for (unsigned int i=0; i<numLines; i++)
imgL[i].resize(numCols);

for (unsigned int i=0; i <numLines; i++)
for (unsigned int j=0; j <numCols; j++)
imgL[i][j]=0;for (int i=0; i<numLines; i++)
for (int j=0; j<numCols; j++)
{
if(img[i][j]=='1'&&imgL[i][j]==0)
{
imgL[i][j]=label;
floodFill (u,v,label,img,imgL);
label++;
}
}
}

1

Решение

Я удалил тонну вашего кода, так как он был не очень актуален, и немного изменил его рефакторинг.

Я действительно не отслеживал каждое изменение, но из того, что я помню:

  1. u а также v передаются и перезаписываются с 0,0, так что больше ничего не проверяется.
  2. Проверка на действительную позицию никогда не проходила, потому что img[p.x][p.y]==1 нужно быть img[p.x][p.y]=='1', Если бы я был тобой, я бы бросил всю эту чарс-вещь и просто использовал бы целые.
  3. img был изменен, а не imgL,
  4. Существует бесконечный цикл, потому что проверка, если точка должна быть добавлена, не проверяет imgL для посещения уже.

Это, кажется, дает желаемый результат:

#include <iostream>
#include <iomanip>
#include <vector>
#include <fstream>
#include <string>

using namespace std;

typedef vector<vector<char> > Image;
typedef vector<vector<int> > ImageLabels;

void showImage(ostream &f, const Image &img)
{
for(size_t i = 0; i < img.size(); i++)
{
for(size_t j = 0; j < img[i].size(); j++)
{
f << setw(3) << img[i][j];
}
f << endl;
}
}

void showImageLabelling(ostream &f, const ImageLabels &imgL)
{
for(size_t i = 0; i < imgL.size(); i++)
{
for(size_t j = 0; j < imgL[i].size(); j++)
{
f << setw(3) << imgL[i][j];
}
f << endl;
}
}

void readImage(istream &f, Image &img)
{
unsigned int numLines, numCols;

f >> numLines;
f >> numCols;

img.resize(numLines);
for(unsigned int i = 0; i < numLines; i++)
{
img[i].resize(numCols);
}

for(unsigned int i = 0; i < numLines; i++)
{
for(unsigned int j = 0; j < numCols; j++)
{
f >> img[i][j];
}
}
}

struct Point
{
Point(int x_, int y_)
: x(x_)
, y(y_)
{}

int x;
int y;
};

bool Valid(size_t x, size_t y, const Image& img, const ImageLabels& imgL)
{
if(x >= img.size() || y >= img[0].size())
{
return false;
}
return img[x][y] == '1' && imgL[x][y] == 0;
}

void floodFill(int x, int y, int label, Image &img, ImageLabels &imgL)
{
static const Point dir[4] =
{
Point(-1,  0),
Point( 0, -1),
Point( 0, +1),
Point(+1,  0)
};

vector <Point> stack;
stack.push_back(Point(x, y));

while(!stack.empty())
{
Point p = stack.back();
stack.pop_back();

imgL[p.x][p.y] = label;

for(int i = 0; i < 4; ++i)
{
int nx = p.x + dir[i].x;
int ny = p.y + dir[i].y;
if(Valid(nx, ny, img, imgL))
{
stack.push_back(Point(nx, ny));
}
}
}
}

void imageLabeling(Image &img, ImageLabels &imgL)
{
const size_t numLines = img.size();
const size_t numCols = img[0].size();

imgL.resize(numLines);
for(unsigned int i = 0; i < numLines; i++)
{
imgL[i].resize(numCols, 0);
}

int label = 1;
for(size_t i = 0; i < numLines; i++)
{
for(size_t j = 0; j < numCols; j++)
{
if(img[i][j] == '1' && imgL[i][j] == 0)
{
imgL[i][j] = label;
floodFill(i, j, label, img, imgL);
label++;
}
}
}
}

int main()
{
Image imgResult;
ImageLabels imgL;

ifstream inFile("img1.txt");
readImage(inFile, imgResult);

cout << "Initial:\n";
showImage(cout, imgResult);
cout << "\n";

imageLabeling(imgResult, imgL);

cout << "After Label:\n";
showImageLabelling(cout, imgL);
cout << endl;

return 0;
}
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]