I'm looking for help, because I wasn't successful finding a function in OpenCV that is able to perform a labelling of connected components on a grayscale image.
**Input:** The input image is an image where there are several larger areas (>500px) with different grayscale intensities, e.g. 0, 50, 100, 150. There are several areas with the same intensity (not touching each other).
**Goal:** output a label mask where each area has it's own label ID, similar to the output of connectedComponentLabelling.
**Problems:** I would have supposed that there is a single function for this in OpenCV, but couldn't find one. I know of very similar functions. I'm pretty much looking for a cv::ConnectedComponents that is able to work on a grayscale image like cv::floodfill does:
* **ConnectedComponents:** extracts connected components from a binary image. I need it for a grayscale image.
* **FindContours:** extracts connected components from a binary image by Canny Edge detection (but for some reason doesn't complain when a grayscale image is the input). This is not very reliable.
* **SimpleBlobDetector:** loops through all intensites and extracts connectedComponents (but the output are keypoints where the area shape is lost).
* **Floodfill**: fills a grayscale connected component with a single color, exactly what I need. But to use this function as a full area extractor I would have to build a loop around it that tests different points etc.. This does not sound like the easiest solution.
* **Distance-Transform and Watershed**: I've seen several solutions with these functions. I don't think this is the right approach for my problem.
* **Meanshift and K-Means**: these functions perform the first filtering step but not the actual label mask.
**My current solution:** A sort-of manual multi-peak Otsu-Threshold or manual meanShift-Filter
* Step 1: get the histogram and find the significant peaks, i.e. all peaks that have x pixels within a delta-range. x is the minimum area, delta is the maximum expected color difference expected within a connected area.
* Step 2: Loop through each peak and perform a cv::inRange() with lowerbound=peak-delta and upperbound=peak+delta. Perform cv::connectedComponents and save the resulting label mask.
* Step 3: combine all label masks to one label mask.
PS: My actual goal is to segment areas by texture and intensity. I have written a function that transforms areas with different textures into areas with different intensity. If somebody knows of a reliable function that segments areas by texture and intensity, even better.
↧