Dilation/erosion on 2D array of chars

526 views Asked by At

I am trying to figure out why my function for dilating an image doesn't produce the correct output.

My goal is to turn something like this:

.........
.........
....x....
.........
.........

into this:

.........
....x....
...xxx...
....x....
.........

for each cycle of dilation.

I haven't thought of it but I also need to to the reverse for the erosion.

This is what I've come up with so far (the program takes in input from the user in the command line using argv) :

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
#include <algorithm>
//look up line by line parsing
using namespace std;
void replacee(vector<vector<char>> &vec, char oldd, char neww)
{
    for (vector<char> &v : vec) // reference to innver vector
    {
        replace(v.begin(), v.end(), oldd, neww); // standard library 
algorithm
    }
}
void dialationn(vector<vector<char>> & vec, char suspect)
{
    for (int i = 0; i < vec.size(); i ++) {
            for (int j = 0; j < vec[i].size(); j++) {
                if (vec[i][j] == suspect) {
                    if (i > 0) {
                     vec[i-1][j] = suspect;
                    }
                    if (j > 0) {
                     vec[i][j-1] = suspect;
                    }
                    if (i + 1<vec.size()) {
                        vec[i+1][j] = suspect;
                    }
                    if (j + 1<vec[i].size()) {
                        vec[i][j+1] = suspect;
                    }
                }
            }
        }
}
int main(int argc, char* argv[]) {

    fstream fin; char ch;
    string name (argv[1]); //File Name.
    vector<vector<char>> data;
    // 2D Vector.
    vector<char> temp;
    // Temporary vector to be pushed 
    // into vec, since its a vector of vectors.
    fin.open(name.c_str(),ios::in);
    // Assume name as an arbitrary file.
    string argument2 (argv[2]);
    string argument3 (argv[3]);
    string argument4 (argv[4]);
    while(fin)
    {
        ch = fin.get();
        if(ch!='\n') {
            temp.push_back(ch);
        }
        else 
        { 
            data.push_back(temp); 
            temp.clear(); 
        }
    }
    if (argument2 == "replace") {
        replacee(data, argument3[0], argument4[0]);
        for (int i = 0; i < data.size(); i ++) {
            for (int j = 0; j < data[i].size(); j++) {
                cout << data[i][j];
            }
            cout << endl;
        }
    } else if (argument2 == "dialate") {
        dialationn(data, argument3[0]);
        for (int i = 0; i < data.size(); i ++) {
            for (int j = 0; j < data[i].size(); j++) {
                cout << data[i][j];
            }
            cout << endl;
        }
    }

    fin.close();
} 

the dialationn function I've implemented so far uses a double for loop to cycle through the 2d array, and when it finds the character that is supposed to be dilated, it checks if a border is near by and sets the coordinate accordingly.

1

There are 1 answers

0
Cris Luengo On

Besides the input parsing issue discussed in the comments to the question, the dilation function proposed by OP doesn't work because it modifies the input image, rather than writing to a new output image. When modifying the input, the result of the dilation for subsequent pixels will be affected.

Correct would be:

void dialationn(vector<vector<char>> & vec, char suspect)
{
    vector<vector<char>> out(vec.size(), vector<char>(vec[0].size(), 0))
    for (int i = 0; i < vec.size(); i ++) {
        for (int j = 0; j < vec[i].size(); j++) {
            if (vec[i][j] == suspect) {
                if (i > 0) {
                    out[i-1][j] = suspect;
                }
                if (j > 0) {
                    out[i][j-1] = suspect;
                }
                if (i + 1<vec.size()) {
                    out[i+1][j] = suspect;
                }
                if (j + 1<vec[i].size()) {
                    out[i][j+1] = suspect;
                }
            }
        }
    }
    swap(out, vec);
}