Single pixel event image processing in python

495 Views Asked by At

I have had a lonng term problem for proceccing a CCD image of a Xray source, It is attached hereCCD image Then after theresholding with an arbitrary value, the thing I need to do is to Subtract the multi-pixel events from the image. I also need to count the number of pixels which belongs to single pixels.

*- By multi pixel I mean the pixels which has nonzero value in sorounding pixels.

I have a code working by using PIL.Image.open() to read it in to a list and do the analysis pixel by pixel! but I'm looking for a standard image prcessing routin for a more reliable and better results. I will appriciate if you can give me how to do it.

Cheers

3

There are 3 best solutions below

0
Alireza Honarfar On BEST ANSWER

First of all I shall thanks @Mark Stechell for his hints and answers. Then I found my nswer by his hint about Hit-or-miss transformation. I found good information in wikipedia as : https://en.wikipedia.org/wiki/Hit-or-miss_transform

then in Python there is a ready made function for this methode which works for me and also for other paterning applications. you will find everithing in below link, it is straigh forward and easy. http://docs.scipy.org/doc/scipy-0.15.1/reference/generated/scipy.ndimage.morphology.binary_hit_or_miss.html

Cheers

9
Mark Setchell On

You can do this quite easily with ImageMagick which is installed on most Linux distros and is available for OSX and Windows. There are C/C++, Python, Perl, PHP, ,Net and other bindings available. I'll just do it at the command line here.

So, here is your start image:

enter image description here

First, let's threshold at an arbitrary 80%:

convert ccd.png -threshold 80% result.png

enter image description here

Now let's find all the white pixels that have no other white pixels around them:

convert ccd.png -threshold 80% -morphology HMT peaks:1.9 result.png

enter image description here

The technique is "Hit-and-Miss Morphology" and it is described here in Anthony Thyssen's excellent ImageMagick usage pages. Search on that page for "Peak" to find the exact paragraph.

Now let's count them:

convert ccd.png -threshold 80% -morphology HMT peaks:1.9 -format "%[fx:int(mean*w*h)]" info:
975

Let's check the multi-pixel events that we removed:

convert ccd.png -threshold 80% \( +clone -morphology HMT peaks:1.9 \) -compose difference -composite result.png

enter image description here

1
Mark Setchell On

I had another attempt at this with the CImg library which is a header-only C++ image processing library that works on all platforms. That is rather nice since there is just one simple header file to copy into your project from the CImg website and you are finished!

See the CImg website here.

The code goes like this:

#define cimg_use_png
#define cimg_display 0
#include <iostream>
#include "CImg.h"

using namespace cimg_library;
using namespace std;

int main() {

   // Load input image
   CImg<unsigned char> im("ccd.png");
   int w=im.width();
   int h=im.height();

   // Create output image and fill with black (0)
   CImg<unsigned char> result(w,h,1,1,0);

   // Total number of white pixels with 8 black neighbours
   int t=0;

   // Threshold image at 80%
   im.threshold(255*0.8);

   // Find, and count, all white pixels with 8 black neighbours
   // Apply Dirichlet boundary conditions at edges - black virtual pixels at edges
   for(int y=0;y<h;y++){
      for(int x=0;x<w;x++){
         if((im.atXY(x,y,0,0)    !=1) ||
            (im.atXY(x-1,y-1,0,0)==1) || (im.atXY(x,y-1,0,0)==1) || (im.atXY(x+1,y-1,0,0)==1) ||
            (im.atXY(x-1,y,0,0)  ==1) || (im.atXY(x+1,y,0,0)==1) ||
            (im.atXY(x-1,y+1,0,0)==1) || (im.atXY(x,y+1,0,0)==1) || (im.atXY(x+1,y+1,0,0)==1)){
         } else {
            t++;
            // Paint output image white
            result(x,y)=255;
            cout << "DEBUG: " << x << "," << y << endl;
         }
      }
   }
   cout << t << endl;
   result.save_png("result.png");
}

And you can compile it with this:

g++ peaks.cpp -o peaks -lpng

Sample Output

This shows the x,y coordinates of pixels that exceed your threshold and have no immediate white neighbours.

DEBUG: 172,1
DEBUG: 287,1
DEBUG: 390,1
DEBUG: 396,1
DEBUG: 536,1
DEBUG: 745,1
DEBUG: 956,1
DEBUG: 72,2
DEBUG: 253,2
DEBUG: 516,2
DEBUG: 671,2
DEBUG: 680,2
DEBUG: 740,2
DEBUG: 811,2
DEBUG: 844,2
DEBUG: 228,3
DEBUG: 282,3
DEBUG: 351,3
DEBUG: 505,3
DEBUG: 551,3
DEBUG: 623,3
DEBUG: 638,3
DEBUG: 689,3
...
...
DEBUG: 797,252
DEBUG: 918,252
DEBUG: 125,253
DEBUG: 357,253
DEBUG: 870,253
DEBUG: 252,254
DEBUG: 941,254
1005