Description of the problem

A number of diseases can be identified from fundus. 
 

...

Typical macular diseases that may be able to solve machine vision

Retinal Artery Occlusion

Retinal Vein Occlusion

Glaucoma Detection From Fundus Image Using Opencv

Retinal Image Graph-Cut Segmentation Algorithm Using Multiscale Hessian-Enhancement-Based Nonlocal Mean Filter

 

State of Art

 

http://www.optomed.com/case+studies/

AUTOMATIC EXTRACTION OF RETINAL BLOOD VESSELS: A SOFTWARE IMPLEMENTATION

 

Fast Marching in 2D

...

 

 

 

 

Examples

...

 

 

Links to excellent studies:

http://www.doria.fi/handle/10024/30354

 

 

---------------------------------------------------------------------------------------------------------------------------------------------------

Retina Investigation Using Machine Vision

2014 Aug.6~Oct.17 Kai Murata (Tokyo National College of Technology)

--------------------------------------------------------------------------------------------------------------------------------------------------- 

1.This project’s objective is to create system that detects diseases. It uses open CV in order to find different abnormal lesions in human eyes.

And this system can use at developing country like Africa. And it works very fast and easy. And I tried to make this algorithm through this project. And I succeed to detect blood vessel area.

 

 2.Research machine vision and preceding study

I read master’s thesis “RETINAL IMAGE ANALYSIS USING MACHINE VISON”. Markku Kuivalainen in Lappeenranta University of Technology Department of Information Technology wrote it. And I studied a lot of things about machine vision. Machine vision can detect color (Fig2.1) and brightness (Fig2.2) easily. And it can use combine. And it also can use masks easily. So this machine vision enables us to have a chance to detect diseases.

 

                               Fig2.1                                                                      Fig2.2

And most famous and image processing library is Open-CV. So I try to use open-CV. And Open-CV can use many kind of platforms. Now I have Macintosh, so I used “Xcode”. But Open-CV program is very simple, so maybe it can use any other platforms like Visual Studio, QT Creator, and so on.  

 3.Tried to create some programs

3.1  Make some masks.

Finally we want to detect blood vessels and some dot area clearly. So it is necessary to create masks. I show original image in (Fig.3.1). I tried to use HSV images of retina images and I detected black area that is not retina images. -(Fig.3.2) And I also make mask to detect not blood vessel area. -(Fig.3.3) This area includes some dot and leaser reflection area. And I tried to make leaser reflection area mask. But it is not so good. -(Fig.3.4) We have to try some other filter to crate this mask.

 

        Fig.3.1 Original Image of Retina                                    Fig.3.2 Mask of Black Area

 

   

           Fig.3.3 Mask of Non Vessel Area                                  Fig.3.4 Mask of Leaser Area 

And I showed you this program sources in end of this document. And this program is C++ with Open-CV for Apple Xcode.

 

3.2  Try to detect blood vessels.

First I tried to detect blood vessels area use hue image. -(Fig3.5) But This image is not accurate and very noisy. So I divide original images RGB channels. Then I use green channel image to detect blood vessels. I showed green image of the retia in (Fig3.6).

                Fig3.5 Hue binary image                                        Fig3.6 Green channel image

 

Next I tried to make binary image to use green channel image. I showed binary images these are different thresholds. Showed in Fig3.7 (a) and Fig3.7 (b).

 

           Fig 3.7 (a) Green channel binary                        Fig 3.7 (b) Green channel binary

 

Image is close to what it’s required to be, but not enough to be able to use it. So I tried to other method. I use dividual threshold. I used 21- neighbor and 31-neighbor. Then I crated binary images use these neighbor. I showed 31-neighbor binary image in Fig3.8 (a) and 21-neighbor binary image in Fig3.8 (b).

 

        Fig3.8 (a) 21-neighbor binary image                       Fig3.8 (b) 31-neighbor binary image

 

These images are better than Fig3.7. But it is still noisy. So I used expansion and contraction 3 times. I showed these images Fig3.9 (a) and Fig3.9 (b).

 

                    Fig3.9 (a) 31-neighbor                                           Fig3.9 (b) 21-neighbor

I think this would be better. But there are some big noises in dot area. So maybe we have to use more masks. I wrote about these things in second chapter.

 

 

3.3  Detect blood vessels area more clearly in the future

Now we can detect almost blood vessel area. But it is has some noise. So we have to use some masks to get more clear images.  I showed combine image mask and Green channel image of retina in Fig 3.10. The brightest white area means mask area. You can see it is almost cover noise area. So may be if we use these mask, we can get more clear images. But now I do not have enough time to make this program. So I think that to make this program will became an issue in the near future.

                   Fig 3.10 Green channel image with some masks

4.Conclusion

I tried to think about this retina project a lot. And I got merit of this project well. And I searched previous research and Machine vision. Then I tried to make some basic programs with Open-CV. I think this project can do with this kind of program, which I made. But it will be need a doctor soon. I really want to ask a doctor about my programs. So in the future, we have to think about medical side. And we have to know, what kind of feature will be required to detect some diseases. I could not do a lot, but I think it was great start. If you use my sample programs, maybe you can start the project quickly. And this program can use almost platforms.

5.Running samples

 




6.Resources and Programs

(1) Thesis

“RETINAL IMAGE ANALYSIS USING MACHINE VISON” Markku Kuivalainen in Lappeenranta University of Technology Department of Information Technology

 

(2) Web Link

http://www.nlm.nih.gov/medlineplus/ency/article/001028.htm

http://maxwellsci.com/print/rjaset/v4-5459-5463.pdf

 

(3) Sources that I made

 (i) This program can make masks.

#include "opencv/cv.h"

#include "opencv/highgui.h"

#include <stdio.h>

#include <sys/stat.h>

#include <sys/types.h>

int main(int argc, char** argv)

{

    IplImage *img=0;

        char* filename = argc == 2 ? argv[1] : (char*)"test.jpg"; //please re name test.jpg (Retina image)

        if( (img = cvLoadImage( filename, 1)) == 0 )

        return -1;

       IplImage* imgH = cvCreateImage(cvGetSize(img), img->depth, 1);

       IplImage* imgS = cvCreateImage(cvGetSize(img), img->depth, 1);

       IplImage* imgV = cvCreateImage(cvGetSize(img),  img->depth, 1);

       IplImage* imgHSV = cvCreateImage(cvGetSize(img), img->depth, img->nChannels );

   

    IplImage* img1 = cvCreateImage(cvGetSize(img),  img->depth, 1);

    IplImage* img2 = cvCreateImage(cvGetSize(img),  img->depth, 1);

    IplImage* imgV1 = cvCreateImage(cvGetSize(img),  img->depth, 1);

    IplImage* imgV2 = cvCreateImage(cvGetSize(img),  img->depth, 1);

 

   

       cvCvtColor(img, imgHSV, CV_RGB2HSV);

       cvSplit(imgHSV, imgH, imgS, imgV, NULL);

    //cvThreshold(imgH, imgH,  125 , 255, CV_THRESH_TOZERO_INV);

       cvThreshold(imgH, imgH, 112 , 255, CV_THRESH_BINARY);

    //cvThreshold(imgS, imgS,  200 , 255, CV_THRESH_TOZERO_INV);

       cvThreshold(imgS, imgS, 100 , 255, CV_THRESH_BINARY);

    //cvThreshold(imgV, imgV,  255 , 255, CV_THRESH_TOZERO_INV);

       cvThreshold(imgV, imgV1, 50 , 255, CV_THRESH_BINARY);

    cvThreshold(imgV, imgV2, 230 ,255, CV_THRESH_BINARY);

    cvAdd(imgV1, imgV2, img1, NULL);

    cvAbsDiff(imgV, imgH, img2);

            //H

    //cvNamedWindow("sikisou",CV_WINDOW_AUTOSIZE);

    //cvShowImage("sikisou",imgH);

    //cvWaitKey(0);

       cvSaveImage("H.JPG",imgH,0);

            //S

       cvSaveImage("S.jpg",imgS,0);

            //V

       cvSaveImage("V1.jpg",imgV1,0); //save masks

       cvSaveImage("V2.jpg",imgV2,0);

    cvSaveImage("img1.jpg",img1,0);

    cvSaveImage("img2.jpg",img1,0);

       cvReleaseImage(&img);

    return 0;

}

 

(ii) This program can make masks.

#include "opencv/cv.h"

#include "opencv/highgui.h"

#include "opencv2/imgproc/imgproc.hpp"

#include <stdio.h>

#include <sys/stat.h>

#include <sys/types.h>

 

IplImage *img=0;

IplImage *channelR=0;

IplImage *channelG=0;

IplImage *channelB=0;

IplImage *channelG1=0;

IplImage *channelG2=0;

IplImage *dotmask=0;

IplImage *raymask=0;

IplImage *jyosan=0;

IplImage *blackmask=0;

 

int main( int argc, char** argv ){

    // input image

    char* filename = argc == 2 ? argv[1] : (char*)"test.jpg";

    if( (img = cvLoadImage( filename, 1)) == 0 )

        return -1;

   

    //devide RGB

    channelR = cvCreateImage(cvSize(img->width,img->height),IPL_DEPTH_8U,1); //Red

    channelG = cvCreateImage(cvSize(img->width,img->height),IPL_DEPTH_8U,1); //Green

    channelB = cvCreateImage(cvSize(img->width,img->height),IPL_DEPTH_8U,1); //B

    channelG1 = cvCreateImage(cvSize(img->width,img->height),IPL_DEPTH_8U,1); //B

    channelG2 = cvCreateImage(cvSize(img->width,img->height),IPL_DEPTH_8U,1); //B

    dotmask = cvCreateImage(cvSize(img->width,img->height),IPL_DEPTH_8U,1); //mask1

    jyosan = cvCreateImage(cvSize(img->width,img->height),IPL_DEPTH_8U,1); //mask1

    raymask = cvCreateImage(cvSize(img->width,img->height),IPL_DEPTH_8U,1); //mask1

    blackmask = cvCreateImage(cvSize(img->width,img->height),IPL_DEPTH_8U,1); //mask1

    cvSplit(img,channelB,channelG,channelR,NULL);

   

    //main

    cvThreshold(channelR, blackmask,50, 255, CV_THRESH_BINARY_INV);

    cvThreshold(channelG, dotmask,90 , 255, CV_THRESH_BINARY);

    cvAdd(channelG, dotmask, jyosan); //mask

    cvAdd(jyosan, blackmask, jyosan); //mask

    cvAdaptiveThreshold(channelG,channelG1, 255,CV_ADAPTIVE_THRESH_GAUSSIAN_C,CV_THRESH_BINARY_INV,31, 4);

    cvAdaptiveThreshold(channelG,channelG2, 255,CV_ADAPTIVE_THRESH_GAUSSIAN_C,CV_THRESH_BINARY_INV,21, 2);

    // dilations & erosions

     int dilations =3;

     int erosions =3;

    if( dilations > 0 )

        cvDilate( channelG1,channelG1,0,dilations );

    if( erosions > 0 )

        cvErode( channelG1,channelG1,0,erosions );

   

    // dilations & erosions

    dilations =3;

    erosions =3;

    if( dilations > 0 )

        cvDilate( channelG2,channelG2,0,dilations );

    if( erosions > 0 )

        cvErode( channelG2,channelG2,0,erosions );

    // Save

    cvSaveImage("jyosan.JPG",jyosan,0);

    cvSaveImage("dotmask.JPG",dotmask,0);

    cvSaveImage("ChannelG.JPG",channelG,0);

    cvSaveImage("ChannelG1.JPG",channelG1,0);

    cvSaveImage("ChannelG2.JPG",channelG2,0);

    cvSaveImage("raymask.JPG",raymask,0);

    cvSaveImage("blackmask.JPG",blackmask,0);

 

    return 0;

}

 

 

  • No labels
You must log in to comment.