13

I have never used image processing with Mathematica. I need to get the coordinates of the red points from this image I made in Illustrator. Is there a way to get Mathematica to read or detect the x-y coordinates?

enter image description here

QuantumDot
  • 19,601
  • 7
  • 45
  • 121

4 Answers4

24

A solution for Mathematica version 9:

image = Import["https://i.stack.imgur.com/R0Dqo.png"]
pts = PixelValuePositions[image, Red, .2];
ListPlot[pts, 
 PlotStyle -> Darker@Orange, 
 PlotMarkers -> {Automatic, .05}, 
 PlotRange -> {{0, 1500}, {0, 800}}, 
 ImageSize -> 600]

listplot of points

cormullion
  • 24,243
  • 4
  • 64
  • 133
8

The question leaves open what a "point" is, as opposed to a pixel.

Attempt at points

If points overlap in the image, it is beyond my skill to separate them. Others here have far more experience in image processing and may be able to suggest things, within limits. If the points are separated, then here's a rough stab at finding them:

MorphologicalComponents[Binarize[img, {0.29, 0.6}], 0.68] // Colorize

MorphologicalComponents

(rules = ArrayRules[MorphologicalComponents[Binarize[img, {0.29, 0.6}], 0.68]];
  points = Mean /@ Map[First, GatherBy[rules, Last], {2}];) // Timing
Length[points]
{0.072981, Null}
195

The points are image coordinates; we should convert them to graphics coordinates before plotting:

ListPlot[{#[[2]], Last@ImageDimensions[img] - #[[1]]} & /@ points, 
 PlotMarkers -> {Automatic, 2}, 
 PlotRange -> Transpose[{{0, 0}, ImageDimensions[img]}], 
 PlotRangePadding -> 50, AxesOrigin -> {0, -50}]

Point plot

Pixels

The same method is an efficient way to get the pixels (especially if you do not have v9 and PixelValuePositions to use).

(rules = ArrayRules[MorphologicalComponents[Binarize[img, {0.29, 0.6}], 0.68]];
  pixelCoords = SparseArray[rules]["NonzeroPositions"];) // Timing
Length@pixelCoords
{0.070562, Null}
2629
ListPlot[{#[[2]], Last@ImageDimensions[img] - #[[1]]} & /@ pixelCoords,
 PlotMarkers -> {Automatic, 0.25}, 
 PlotRange -> Transpose[{{0, 0}, ImageDimensions[img]}], 
 PlotRangePadding -> 50, AxesOrigin -> {0, -50}]

Pixel plot


This way is nearly as fast and gives the same result as above:

pixelCoords = Position[ImageData@Binarize[img, {0.29, 0.6}], 1]; // Timing
Length@pixelCoords
{0.108690, Null}
2629
Michael E2
  • 235,386
  • 17
  • 334
  • 747
  • Good work, +1. Although we're probably all just exploring for fun, since the OP's Illustrator file likely contains the actual coordinate pairs of every point – cormullion Jun 04 '13 at 19:39
  • @cormullion Yes, processing images is an attractive pastime, but it's not something I am very good at yet. – Michael E2 Jun 04 '13 at 23:40
4

Using relatively simple functions:

c = Import["https://i.stack.imgur.com/R0Dqo.png"] ;
a = Rasterize[c];
reds = Cases[Union[Flatten[a[[1, 1]], 1]], {r_ /; r > 200, g_ /; g < 50, b_ /; b < 50}];
Row[{First[Timing[b = Map[Position[a[[1, 1]], #] &, reds]]], " seconds"}]

13.073 seconds

ListPlot[Reverse /@ Flatten[b, 1], PlotStyle -> Red, AxesOrigin -> {0, 0}]

enter image description here

azerbajdzan
  • 15,863
  • 1
  • 16
  • 48
Chris Degnen
  • 30,927
  • 2
  • 54
  • 108
3

Another way without Mathematica version 9 PixelValuePositions

img = Import["https://i.stack.imgur.com/R0Dqo.png"];
pix = Round[ImageData[img, DataReversed -> True]];
ListPlot[Reverse /@ Position[pix, {1, 0, 0}], AxesOrigin -> {0, 0}] 

enter image description here

dstahr
  • 381
  • 1
  • 3
  • 8