component_labeling.hpp

Back to Labeling

pastel/gfx/image_processing/

#ifndef PASTELGFX_COMPONENT_LABELING_HPP
#define PASTELGFX_COMPONENT_LABELING_HPP

#include "pastel/gfx/image_processing/component_labeling.h"

namespace Pastel
{

    template <
        typename Image_ConstView,
        typename Result_View
    >
    void labelConnectedComponents(
        const ConstView<2, bool, Image_ConstView>& image,
        const View<2, uint32, Result_View>& result)
    {
        integer width = image.width();
        integer height = image.height();

        result.setExtent(width, height);

        if (width == 0 ||
            height == 0)
        {
            return;
        }

        integer NoComponent = 0;
        integer nextComponent = 1;

        // Handle the bottom left pixel.

        if (image(0, 0))
        {
            result(0, 0) = nextComponent;
            ++nextComponent;
        }
        else
        {
            result(0, 0) = 0;
        }

        // Handle the bottom row.

        for (integer x = 1;x < width;++x)
        {
            if (image(x, 0))
            {
                if (result(x - 1, 0) != NoComponent)
                {
                    result(x, 0) = result(x - 1, 0);
                }
                else
                {
                    result(x, 0) = nextComponent;
                    ++nextComponent;
                }
            }
            else
            {
                result(x, 0) = NoComponent;
            }
        }

        // Handle the rest of the pixels.

        for (integer y = 1;y < height;++y)
        {
            // Handle the left-most pixel.

            if (image(0, y))
            {
                integer below = result(0, y - 1);
                if (below != NoComponent)
                {
                    result(0, y) = below;
                }
                else
                {
                    result(0, y) = nextComponent;
                    ++nextComponent;
                }
            }
            else
            {
                result(0, y) = NoComponent;
            }

            for (integer x = 1;x < width;++x)
            {
                if (image(x, y))
                {
                    integer left = result(x - 1, y);
                    integer below = result(x, y - 1);

                    if (left != NoComponent)
                    {
                        if (below != NoComponent)
                        {
                            if (left == below)
                            {
                                result(x, y) = left;
                            }
                            else
                            {
                                // left and below components
                                // are the same component with
                                // different labeling.
                            }
                        }
                        else
                        {
                            result(x, y) = left;
                        }
                    }
                    else
                    {
                        if (below != NoComponent)
                        {
                            result(x, y) = below;
                        }
                        else
                        {
                            result(x, y) = nextComponent;
                            ++nextComponent;
                        }
                    }
                }
                else
                {
                    result(x, y) = NoComponent;
                }
            }
        }
    }

}

#endif