Automatically detect - remove shapes on more images (and inpaint them)

Hello everyone,

In case you are interested here are 4 .jpg images to test (zip folder - Dropbox):
images

There is one (coins.jpg) which might be tricky because there are plenty of coins :slight_smile:

Remove the alpha channel from coins.png. That’s the ‘different spectrums’ error. G’MIC, in its charming way, calls the aggregate number of channels the image’s spectrum.

Here’s the rough workflow

  1. devise a mask of your ‘benchmark euro’ Use that for the entire batch. It could look something like my 64,64,1,3 mask of your euro. I just cropped it from your botanical.
  2. Iterate over the batch, using something like my pipeline . For each image:
  3. The third image in the list has been derived from the correspondence map to isolate the coin. Let us call it the ‘correspondence mask’
  4. Use one copy of the correspondence mask as a mask for inpaint_morpho. to blot out the coin in your botanic image - select the botanic, pass the mask as an argument.
  5. -input your centimeter scale from wherever you stash your centimeter scales. That, having an alpha channel, can be alpha-composed onto the botanical image. The barycenter coordinates identify the center of the coin, Or look at @Reptorian 's script: he locates the upper left corner of the image (he doesn’t use barycenter)
  6. Use image to composite the scale and the botanical image. The centimeter scale would be the ‘sprite’ image and the botanical the selected image. The x,y coordinate arguments to image locates the upper-lefthand corner of the sprite. depth, z, and channel, c, are zero and opacity is = 1.
  7. Output the composite botanical+centimeter scale and move onto the next botanical, reusing the coin mask. -remove any other intermediary image (correspondence mask and such)

I think 1-7 can be wholly automatic; but NB my black-eye susan comment made to @prawnsushi. Some images may break. When I get home and after the puppy walk, I think I can script this out.

That’s it for now. Hope this helps.

@grosgood

Remove the alpha channel from coins.png

Thanks. Somewhat, It did the trick :slight_smile:

I have an approach that may work for all cases in context of selection.

apple1.jpg apple2.jpg blueberry.jpg foreach { rgb2lch split c keep[1] gt 20 }

Here’s the problem. Filling those little holes that shows up. After that, it’s just a matter of detecting circle with matchpatch or by area-size selection, and using inpaint, and then using image command to do the 2cm thing.

Right now, I don’t feel like finishing this up, so I will give pointers instead.

Tee, Hee. Did a rather better job of picking the apple rather than the euro, no? I expected that contrary cases could arise; am hoping that contrary cases could be small in number or constrained (ever the optimist). Leaving the office now. Thanks for something to ponder on whilst riding on the subway and walking The Little Mutt…

And thank you for the interesting problem!

Here’s the code:

rep_tool_for_silvio_grosso_detect_and_inpaint_and_insert_2_cm:

foreach {
 +rgb2lch split[-1] c keep[0,-2] gt[-1] 15
 +area[-1] 0,0 
 lt[-1] 900
 if iv
  inpaint_pde[-2] [-1],0,0,0
 fi
 rm[-1]
 area_fg[-1] 0,1
 +gt[-1] 1000 *[-2] [-1] rm.
 +colormap[-1] 0
 for w#-1>4 {
  +gt. {ia} *[-2] [-1] rm. colormap. 0 
 }
 eq[-2] {i(#-1,1)} rm.
 dilate[-1] 6
 inpaint_pde[-2] [-1],100%,2,1
}

Not really a good result, but oh well.

@Silvio_Grosso , what you need here is clearly a circle detector (usually implemented with the Circle Hough Transform (CHT)), as the coins in your images have different sizes and colors.

CHT is not already implemented in G’MIC, but 100% sure it can be done (the classical hough transform for detecting lines is implemented and works as expected).
It could be a nice addition TBH.

Once the coin is detected, using one of the inpaint method of G’MIC should be OK to remove it.

Hello David,

Thanks a lot for your reply: you certainly know where the problem lies :slight_smile:

Luckily for me, pretty much all my images have a white background.
Some of them, which I can fix manually, have a black one (because the white would not be fitting)

I suppose that, once the coin in every jpg image is detected, in-painting AND adding automatically the 2 cm graduated scale should be “trivial” :slight_smile:

Btw, many of my images have more perfect “circles” on them (petri dish for plant pathology…) :slight_smile:

Anyway, once again, thanks a lot indeed for your work on G’MIC over the years :slight_smile:

Even if your have other circle-shaped structures in your image, it should not be that hard to avoid detecting them as coins, because of the constraint we can put on the circle radius that should lie within a particular range.

I’m really busy at the moment (I have an audition in Paris tomorrow), but I might try to implement the Circle Hough Transform in G’MIC by the end of May, if I have some time.

I’m pretty sure that it could be a fun challenge for @grosgood or @garagecoder too :wink:

Hello @David_Tschumperle

I’m really busy at the moment (I have an audition in Paris tomorrow), but I might try to implement the Circle Hough Transform in G’MIC by the end of May, if I have some time.

Sure. No problem at all :slight_smile:

@David_Tschumperle

Bonjour,

It’s a good idea to create this function to detect circles.
I saw that this function existed in the OpenCV library : HoughCircles()
In the examples found on the internet this function is very simple to use.
I await the equivalent in G’MIC with great interest :o)

Hello @samj

I saw that this function existed in the OpenCV library : HoughCircles()

A colleague of mine, told me it could perhaps be available within R as well (https://www.r-project.org/).

In the long past, 10 years ago or so, at work, we had some petri dish where we need to measure the area of the fungi growing on them.
A researcher wrote a script to detect them from my jpeg pictures and It worked extremely well. Unfortunately, he doesn’t work with us anymore :slight_smile:

CHT - Was reading up on it in the wee hours. Alas! @Silvio_Grosso has shot — what, ten million? — botanicals already with five euro pieces; otherwise suggesting using a square target was on my lips, and the present hough would handle squares in a straightforward way.

Remarks on using matchpatch to follow. Not a total failure, but not 100% success either.

Indeed, matchpatch won’t manage changes in color/intensity/sizes between the actual photograph and the template image very well.
I don’t think it’s a good approach considering the variety of photographs shot by @Silvio_Grosso .

Been a fun evening. Thank you, @Silvio_Grosso !

apple1_out
That was pretty slick.
apple2_out
OOPS! Coin too close to the apple. Can’t do anything about that. Also, had to tweak settings a bit to have success. In the real world, that means manual intervention.
blueberry_out
Ah — this was actually a FAIL, because I had to use a lightened version of the “standard euro coin”. In the real world, that also means intervention.
coinplant_out
Success. This, of course, was the sweet spot photograph where all the stars align.

This is my script, for the curiosity of it all

matchit : -check ${"is_image_arg\ $1"} -skip ${2=0.25},${3=5},${4=0.25}
   cutoff,ed,ps=${2-4}
   pass$1 1
   =>. patch
   foreach[^patch] {
      ma=-1
      ml=-1
      bc=-1,-1
      =>. unkwn
      pass[-1] 1
      =>. patch
      +matchpatch[unkwn] [patch],{$ps*w#$patch},{$ps*h#$patch},1,20,0,-0.005,1   d ,
      -channels. 2                                                             d ,
      -fill. ">begin(cv=$cutoff*(iM-im);print(cv));i(x,y)<cv?1:0"              d ,
      -erode. $ed
      -dilate. $ed
      -label_fg. 0,1                                                           d ,
      =>. areas
      -repeat {iM#$areas}
         [areas]                             
	 -eq. {$>+1}
	 +barycenter.
	 -area.. 0,1
	 -if i(#-2,{@0,1})>$ma
	    ma={i(#-2,{@0,1})}
	    ml={$>+1}
	    bc={@0,1}
	 -fi
         -keep[areas,unkwn,patch]
      -done
      -fill[areas] i(x,y)==$ml
      +autocrop[areas]
      -circle.. $bc,{1.5*sqrt(w^2+h^2)/2},1,1
      -remove.
      -inpaint_morpho[unkwn] [areas]
      -remove[patch]
   }
   -remove[patch,areas]

And these were the command lines that produced the images above.

 gmic matchit.gmic -input coinplant.jpeg -input coin.png matchit[-2] [-1],0.01,5,0.16   OK
 gmic matchit.gmic -input apple1.jpg     -input coin.png matchit[-2] [-1],0.01,5,0.16   OK
 gmic matchit.gmic -input apple2.jpg     -input coin.png matchit[-2] [-1],0.03,5,0.20   ADJ Coin too close to botanical
 gmic matchit.gmic -input blueberry.jpg  -input coin_light.png matchit[-2] [-1],0.05,5,0.35 ADJ+ADJMSK

So — if I had to intervene to adjust arguments or change the matching patch, I marked it as a ‘FAIL’. So I’m batting about 50% — way too low for the Real World. I’d like to be able to load a hundred images and realize success in about 98% of them. I could tolerate fixing two out of a hundred. But not half. May as well use GIMP. As David could attest, matchpatch plays a statistical game, but matchpatch can’t tolerate modest levels of variance. Loosen restrictions, and bit and pieces of plants look too much like euros. Tighten restrictions, and the euro is never seen. I started looking at CHT at about 11 PM, then dozed off around midnight. I’ll be fine after about 20 ounces of strong coffee…

Onto CHT!!!

2 Likes

Hello @grosgood

@Silvio_Grosso has shot — what, ten million?

Milion not, but thousands is quite likely :slight_smile:

Just to give you an example of a “single” session of a working day:

I always try hard to take only one very best shot per sample in order to reduce the amount of fixing up later (with RawTherapee and GIMP). For instance, I always use a tripod, the lowest amount of ISO etc etc

A former colleague of mine, now retired, told me that “a good photographer must try to learn how to shoot the least amount of pictures per day”.
Usually beginners take a lot of pictures because they are not sure about the final results (and usually have plenty of time to fix them later on…).

Perhaps a simple general rule will cover 98% of cases. For example, “The coin is the smallest circle that is not inside a larger circle, and with a radius that is at least 15 pixels”.

And perhaps another simple rule will cover 98% of the rest.

HA! Economy in expression! How often that crops up in so many endeavours!

The Writer’s Lament: “I am sorry I wrote such a long letter. I did not have time to write a short one.”

Attributed, I believe, to Sun Tzu: “To gain knowledge: add. To gain wisdom: subtract.”

As @David_Tschumperle noted, the better euro coin finder is probably the Circular Hough Transform, a generalization of the linear version already in G’MIC. The major pieces for a generalization are lying around. BUT, even there I foresee difficulties: round petri dishes, round bacterial colonies, round euros. Betwixt Scylla and Charybdis there is but a narrow way…

EDIT:

There is that…

Previous pictures of petri dish were about fungi.

As regards the bacteria, here they are:

For bacteria, which are usually white-yellowish, I usually put a black background.

Erwinia amylovora, in this picture is quite a big problem for plants in the USA too.
Actually, it was “imported”, by accident, in Europe from the USA many years ago and now it is quite established :slight_smile:

That’s why it is good that you are the plant pathologist. me: “bacteria, fungi, whydayawannaknowthediff anyway?”