Tasos
Created February 2, 2020 © GPL3+

Training Assistant for Melanoma Signs Detection

Nano provides the necessary tools to construct portable devices that can be used for educational purposes and as mass screening assistants.

AdvancedFull instructions provided2 days41
Training Assistant for Melanoma Signs Detection

Things used in this project

Hardware components

NVIDIA Jetson Nano Developer Kit
NVIDIA Jetson Nano Developer Kit
×1

Story

Read more

Schematics

JETSON NANO

Code

image.py

Python
Classify skin lseion images with a GUI environment.
#!/usr/bin/env python
##############################################################################
# Modified by Tasos from Hajime Nakagami<nakagami@gmail.com>
# (http://www.freebsd.org/copyright/freebsd-license.html)
#
# 2020
##############################################################################
import PIL
import PIL.Image
import numpy as np
import jetson.inference
import jetson.utils

import cv2
import matplotlib.pyplot as plt

import argparse
import sys
import os

try:
    from Tkinter import *
    import tkFileDialog as filedialog
except ImportError:
    from tkinter import *
    from tkinter import filedialog
import PIL.ImageTk

class App(Frame):

    def process(self):
        os.system('PATH/imagenet-console_mine.py --model=PATH_TO_CONVERTED_MODEL/resnet18a.onnx --input_blob=input_0 --output_blob=output_0 --labels=PATH_TO_LABELS/labels.txt TEMP_PATH/current.jpg')
        self.im = PIL.Image.open('TEMP_PATH/processed.jpg')
        self.chg_image()
        
       
    def chg_image(self):
        self.num_page=self.num_page+1
        if self.im.mode == "1": # bitmap image
            self.img = PIL.ImageTk.BitmapImage(self.im, foreground="white")
        else:              # photo image
            self.img = PIL.ImageTk.PhotoImage(self.im)
        
        w = int(self.img.width())
        h = int(self.img.height())
        if w>1280 or h>720:
            wd=int(w*0.3)
            hg=int(h*0.3)
            newsize = (wd, hg) 
            self.im = self.im.resize(newsize) 
        elif w<640 or h<480:
            wd=640
            hg=480
            newsize = (wd, hg) 
            self.im = self.im.resize(newsize)
        else:   
            wd=w
            hg=h    

        if self.im.mode == "1": # bitmap image
            self.img = PIL.ImageTk.BitmapImage(self.im, foreground="white")
        else:              # photo image
            self.img = PIL.ImageTk.PhotoImage(self.im)   
        
        self.la.config(image=self.img, bg="#000000", width=wd, height=hg)
       

    def open(self):
        filename = filedialog.askopenfilename()
        if filename != "":
            self.im = PIL.Image.open(filename)
            self.num_page=self.num_page+1
            self.im.save('TEMP_PATH/current.jpg')
        self.chg_image()
        if self.num_page==2:
            Button(self, text="Process", command=self.process, fg='green').pack(side=TOP)
        

    def capture(self):
        cap=cv2.VideoCapture(0)    
        ret, capimg=cap.read()
        capimg=cv2.cvtColor(capimg, cv2.COLOR_BGR2RGB)
        self.im=PIL.Image.fromarray(capimg)
        self.num_page=self.num_page+1
        self.im.save('TEMP_PATH/current.jpg')
        self.chg_image()
        if self.num_page==2:
            Button(self, text="Process", command=self.process, fg='green').pack(side=TOP)

    def quit(self):
        self.destroy()
        exit()
        

    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.master.title('Skin Lesions Classifier Assistant')
        self.num_page=0
        

        fram = Frame(self)
        Button(fram, text="Open File", command=self.open).pack(side=LEFT)
        Button(fram, text="Camera Frame", command=self.capture, fg='orange').pack(side=LEFT)
        Button(fram, text="Quit", command=self.quit, fg='red').pack(side=LEFT)
        
        fram.pack(side=TOP)
        self.la = Label(self)
        self.la.pack()

        self.pack()

if __name__ == "__main__":
    
    root=Tk()
    root.minsize(640,480)
    app = App(root)
    app.mainloop()

imagenet-console_mine.py

Python
Used by image.py for performing the actual image classification.
#!/usr/bin/python
#
# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
#

#Adapted by Tasos 2020

import jetson.inference
import jetson.utils

import argparse
import sys
import cv2
import matplotlib.pyplot as plt
import PIL
from PIL import ImageDraw, ImageFont
from PIL import Image

# parse the command line
parser = argparse.ArgumentParser(description="Classify an image using an image recognition DNN.", 
						   formatter_class=argparse.RawTextHelpFormatter, epilog=jetson.inference.imageNet.Usage())

parser.add_argument("file_in", type=str, help="filename of the input image to process")
parser.add_argument("file_out", type=str, default='TEMP_PATH/processed.jpg', nargs='?', help="filename of the output image to save")
parser.add_argument("--network", type=str, default="googlenet", help="pre-trained model to load (see below for options)")

try:
	opt = parser.parse_known_args()[0]
except:
	print("")
	parser.print_help()
	sys.exit(0)

# load an image (into shared CPU/GPU memory)
img, width, height = jetson.utils.loadImageRGBA(opt.file_in)
im_t = PIL.Image.open(opt.file_in)

# load the recognition network
net = jetson.inference.imageNet(opt.network, sys.argv)

# classify the image
class_idx, confidence = net.Classify(img, width, height)

# find the object description
class_desc = net.GetClassDesc(class_idx)

# print out the result. Set Classification Level over 60%
if confidence*100>60:
    print("image is recognized as '{:s}' (class #{:d}) with {:f}% confidence\n".format(class_desc, class_idx, confidence * 100))
else:
    print('Insufficient Classification')	

# print out timing info
net.PrintProfilerTimes()

# overlay the result on the image
w = width
h = height
if w>1280 or h>720:
            wd=int(w*0.3)
            hg=int(h*0.3)
            newsize = (wd, hg) 
            im_t = im_t.resize(newsize) 
elif w<640 or h<480:
            wd=640
            hg=480
            newsize = (wd, hg) 
            im_t = im_t.resize(newsize)
else:   
            wd=w
            hg=h  
if opt.file_out is not None:
	im_t.save(opt.file_out)
	img = Image.open(opt.file_out)
	# Select Font type and size
	font=ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', 18)
	d = ImageDraw.Draw(img)
	if confidence*100>60:
		conf=round((confidence * 100), 2)
		caption='Image Classified as: '+class_desc+' @ '+str(conf)+'% Confidence'
		#fontsize=16
		d.text((10,10), caption, font=font, fill=(255, 255, 255, 255))
	else:
		conf=round((confidence * 100), 2)
		caption='Inconclusive @ '+str(conf)+'% Confidence'
		
		d.text((10,10), caption, font=font, fill=(255, 255, 0, 255))
	img.save(opt.file_out)	
	
        
    
    	

excellCopy.py

Python
Excell Manipulation Python Script for training data preparation.
#!/usr/bin/python

#Tasos 2020

import xlrd 
import os
  
# Location of the excel file 
loc = (β€˜PATH to Excel File/Metadata_2_columns.xlsx’) 
wb = xlrd.open_workbook(loc) 
sheet = wb.sheet_by_index(0)
flag=1
i=0
imgpath= β€˜PATH to first Images Files +'ham10000\HAM10000_images_part_1'

try:
    os.chdir(imgpath)
    print(os.getcwd())
except:
    print('Failed')    

#Start with First class "Actinic keratoses"
i=1
while flag:
    cval=sheet.cell_value(i, 1)
    if cval=='akiec':
        name=sheet.cell_value(i, 0)+'.jpg'
        
        os.system('copy '+name+’ β€˜+'PATH to training data location+’+’\akiec') 
        i=i+1
    else:
        flag=0
flag=1

#Continue with Second class "Basal cell carcinoma"

while flag:
    cval=sheet.cell_value(i, 1)
    if cval=='bcc':
        name=sheet.cell_value(i, 0)+'.jpg'
        
        os.system('copy '+name+’ β€˜+'PATH to training data location+’+’\bcc') 
        i=i+1
    else:
        flag=0

flag=1
#Continue with Third class "Benign Keratosis"

while flag:
    cval=sheet.cell_value(i, 1)
    if cval=='bkl':
        name=sheet.cell_value(i, 0)+'.jpg'
        
        os.system('copy '+name+’ β€˜+'PATH to training data location+’+’\bkl') 
        i=i+1
    else:
        flag=0

flag=1
#Continue with Fourth class "Dermatofibroma"

while flag:
    cval=sheet.cell_value(i, 1)
    if cval=='df':
        name=sheet.cell_value(i, 0)+'.jpg'
        
        os.system('copy '+name+’ β€˜+'PATH to training data location+’+’\df') 
        i=i+1
    else:
        flag=0

flag=1
#Continue with Fifth class "Melanoma"

while flag:
    cval=sheet.cell_value(i, 1)
    if cval=='mel':
        name=sheet.cell_value(i, 0)+'.jpg'
        
        os.system('copy '+name+’ β€˜+'PATH to training data location+’+’\mel') 
        i=i+1
    else:
        flag=0

flag=1
#Continue with Sixth class "Melanocytic nevi"

while flag:
    cval=sheet.cell_value(i, 1)
    if cval=='nv':
        name=sheet.cell_value(i, 0)+'.jpg'
        
        os.system('copy '+name+’ β€˜+'PATH to training data location+’+’\nv') 
        i=i+1
    else:
        flag=0

flag=1
#Continue with Seventh class "Vascular skin lesions"

while flag:
    cval=sheet.cell_value(i, 1)
    if cval=='vasc':
        name=sheet.cell_value(i, 0)+'.jpg'
        
        os.system('copy '+name+’ β€˜+'PATH to training data location+’+’\vasc') 
        i=i+1
    else:
        flag=0

Credits

Tasos

Tasos

10 projects β€’ 2 followers

Comments