1
$\begingroup$

I apologize if the question is somewhat vague - it is a bit difficult to put succinctly in one line what I am trying to do. I wrote a program to take the binarized data of an image and then generate outlines from one side to the other. For example, take the following image:

enter image description here

Now I run the piece of code, given by getOutline, which will draw a blue line such that I can divide this into three different parts.

    boxTest = (ImageData@ Binarize[ Import["https://i.stack.imgur.com/JT3eI.png"]]) /. {0 -> 1, 1 -> 0};
    ArrayPlot[getOutline[boxTest, {160, 290, 460}, "lc"],ColorRules -> {0 -> White, 0.5 -> Blue, 1 -> Black},  ImageSize -> Full]

enter image description here

Even though it isn't important, here,getouline has inputs of the array(boxTest), the starting values ({160, 290, 460}) and the direction of travel("lc" - which stands for left to right clockwise).

What I want to know is; how do I crop this image, which is actually an array of {0,0.5,1}'s, such that I can obtain three new arrays - which will then of course be formed into three separate images.

The spirit of it would be:

    outlineArray = [getOutline[boxTest, {160, 290, 460}, "lc"];
    dividedArray= splittingFunction[outlineArray];

Now, dividedArray would have three elements, first element corresponding to: the dot, star and cloud array data, second element: the line and small star and the third element would be: the arrow and lightning. Of course once the arrays are cropped they would be put placed onto a padded array of zero's. That way when doing ArrayPlot/@dividedArray I will have a nice images of the array data for all elements in dividedArray which I could then export.

If the line separating the images were straight lines, then there is no problem. It's the fact that the blue outlines have this contouring property which stumps me - I do have a few potential solutions in mind, but they are rather dirty.

Thanks in advance

$\endgroup$
  • $\begingroup$ I'm not sure I understand. Don't the blue lines divide the image into 4 segments? $\endgroup$ – bill s Nov 9 '17 at 22:29
  • 1
    $\begingroup$ No, it would 1st: everything from top-> first blue line, then 2nd: everything between first blue line-> second blue line, and third: everything between second-> third blue line. Third blue line->bottom is ignored as if you look carefully it doesn't contain any images. Also, I'm not sure if you can see it clearly, but the blue lines actually go around the images, hugging them. $\endgroup$ – Luca Pontiggia Nov 9 '17 at 22:35
1
$\begingroup$

Seeing as I found a solution to my problem, I thought I would write it down as an answer. I wouldn't say it is very elegant, but it gets the job done. The function is the following:

cutSnipets[outlineArray_] :=  Module[{cutCopy, outTemp, eC, sepSnips, r, element, dim},
      dim = Dimensions@outlineArray;
      cutCopy = ConstantArray[0, dim];
      outTemp = outlineArray;
      eC = Reverse[Sort[DeleteDuplicates[Flatten@outlineArray]][[2 ;; -2]]];
      sepSnips = 
       Table[
         Do[
             r = dim[[1]];
             element = outTemp[[r, c]];
             While[element != eC[[k]],
             element = outTemp[[r, c]];
             cutCopy[[r, c]] = element;
             outTemp[[r, c]] = 0;
             r = r - 1;];
           , {c, dim[[2]]}
           ];
       cutCopy = cutCopy /. {eC[[k]] -> 0};
       outTemp = outTemp /. {eC[[k]] -> 0};
       cutCopy
     , {k, Length@eC}];
    sepSnips = AppendTo[sepSnips, outTemp];
    Reverse[sepSnips]
   ];

The code scans the image from the bottom upwards starting from the left and going right. The image needs to have different colors for each lines which corresponds to different values in the array {0.1,0.2,0.3...}.This means the image will look as follows:

enter image description here

We start from bottom left, for as long as every element in the image is a 1 or 0, then the element will be copied to a blank canvas (cutCopy) until the, the element is a color. At which point it will then reset and start from the next column. While this is happening, if an element is black (1) then it gets erased. This way when the loop has gone across all columns the resulting image (outTemp) will contain only everything from above the blue line. The process is the repeated for however many colored lines there are. So:

 boxTest = (ImageData@ Binarize[Import["https://i.stack.imgur.com/JT3eI.png"]]) /. {0 -> 1, 1 -> 0};
 outlineArray = getOutline[boxTest, {170, 290}, "lc"];
 dividedArray = cutSnipets[outlineArray];

 ArrayPlot/@dividedArray

Which gives

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.