1

I need to segment an image, based on a simple rule (if value is in between 2 values). I'm using only STL containers (I'm not using opencv or other libraries because I want to keep this free of dependencies while teaching myself c++)

I've stored my images as vector< vector<double> >. My brute force approach is to iterate through my image using 2 iterators and check each value, and maybe push the indices of the values that satisfy my condition to another vector<int>. I'll have to do this until all segments are found. Every time I want to pick a segment I'll iterate through the stored indices.

  1. What is the correct way to do this?

  2. Can this be achieved in one pass?

  3. What is a suitable STL container for this process? I'm trying to figure it out through this flowchart. The best I can come up with was an unordered_multimap.

Community
  • 1
  • 1
Kuravi H
  • 101
  • 1
  • 8
  • 1
    vectors are great for images, but generally it works out better to use a `std::vector` and then your index is `vec[currColumn*numRows + currRow]`. That way your image is in one, contiguous, cache-friendly piece of memory. – RyanP Dec 14 '16 at 18:23
  • Good to know, I made it 2d purely for readability, nothing else, did not know the performance implications. will switch to 1d. – Kuravi H Dec 14 '16 at 18:38
  • What do you mean by segment here? – Surt Dec 14 '16 at 21:11
  • similar to this [opencv python example](http://docs.opencv.org/3.1.0/d3/db4/tutorial_py_watershed.html). each coin would be a segment. – Kuravi H Dec 15 '16 at 00:15

2 Answers2

0

If you're moving elements to the end of the vector, use std::stable_partition.

std::vector<int> vec(20);
// 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

std::iota(begin(vec), end(vec), 0);
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 

std::stable_partition(begin(vec), end(vec),
                      [](const auto& e){ return (4 <= e && e < 12);});
// 4 5 6 7 8 9 10 11 0 1 2 3 12 13 14 15 16 17 18 19

Online example here.

This will also work if you store the data in a single vector - use iterators for the beginning and end of the column/row instead of the entire range. I've got no idea how you read 'across' the data sensibly with either a 1D or 2D vector though!

(I wrote a very nice post about Sean Parent's gather algorithm before realising it doesn't answer the question. View the edit history if you want to move selected items to places other than the ends.)

Jack Deeth
  • 3,062
  • 3
  • 24
  • 39
-1

If the image is divided to two segments, you can store the segmentation as vector<vector<bool>> with the same size as the image.

khuttun
  • 683
  • 1
  • 4
  • 14