#Import Required Packages import numpy as np import gradio as gr #from google.colab.patches import cv2_imshow import cv2 import matplotlib.pyplot as plt import numpy as np import skimage import imutils from imutils import contours def figplota(xvalues): fig = plt.figure() plt.plot(xvalues, figure=fig) return fig def quant(imageinput): #@title Please Input the Lateral Flow Assay Image # read image using openCV #path = "/content/l1.jpg" image = cv2.imread(imageinput)#imageinput target = "PKU" #print(image) #cv2_imshow(image) # Convert the image to grayscale BGR2RGB = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) gray = cv2.cvtColor(BGR2RGB, cv2.COLOR_RGB2GRAY) #print(gray) #cv2_imshow(gray) # Invert the image to negative scale negative = cv2.bitwise_not(gray) negativeimage = negative.copy() #save a copy to avoid disrupting the image contour #print(negativeimage) #cv2_imshow(negativeimage) # Minimize the noisy effects of artificats using Gaussian blur (helps with minimizing the effect of noisy artifactual bright-spots) blur = cv2.GaussianBlur(negativeimage, (11, 11), 0) #print(blur) #cv2_imshow(blur) # Binarize Image threshold = float(cv2.meanStdDev(blur)[0]) + 0.6*float(cv2.meanStdDev(blur)[1]) imgthreshold = cv2.threshold(blur, threshold, 255, cv2.THRESH_BINARY)[1] #print(imgthreshold) #cv2_imshow(image_thresh) # Reducing noise noise through eroding & eroding imgeroding = cv2.erode(imgthreshold, None, iterations=1) zeronoise = cv2.dilate(imgeroding, None, iterations=1) #print(zeronoise) #cv2_imshow(zeronoise) # CCA the threshold Image import skimage.measure labels = skimage.measure.label(zeronoise, background=0) masking = np.zeros(zeronoise.shape, dtype="uint8") for label in np.unique(labels): if label == 0: continue MaskL = np.zeros(zeronoise.shape, dtype="uint8") MaskL[labels == label] = 255 numPixels = cv2.countNonZero(MaskL) if numPixels > masking.shape[1]*3: masking = cv2.add(masking, MaskL) #cv2_imshow(mask) # Find the contours and sort, please change from bottom-to-top to top-to-bottom accordingly contourss = cv2.findContours(masking.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) contourss = imutils.grab_contours(contourss) contourss = contours.sort_contours(contourss, method="bottom-to-top")[0] #change here accordingly final= [] if len(contourss) > 1: for (i, c) in enumerate(contourss): # draw the bright spot on the image for the control and sample band x, y, width, height = cv2.boundingRect(c) final.append(negativeimage[y:y+height, x:x+width]) rect = cv2.minAreaRect(c) box = cv2.boxPoints(rect) # convert all coordinates floating point values to int box = np.int0(box) # draw a rectangle cv2.drawContours(image, [box], 0, (0, 0, 255), thickness=2) elif len(contourss) == 1: # draw the bright spot on the image for the control band for (i, c) in enumerate(contourss): x, y, width, height = cv2.boundingRect(c) final.append(negativeimage[y:y+height, x:x+width]) rect = cv2.minAreaRect(c) box = cv2.boxPoints(rect) # convert all coordinates floating point values to int box = np.int0(box) # draw a rectangle cv2.drawContours(image, [box], 0, (0, 0, 255), thickness=2) box_ctl_final = np.array([[0,height], [0,0], [width,0], [width,height]]) final_test_1 = negativeimage[height:2*height, 0:width] final_test_2 = negativeimage[2*height:3*height, 0:width] if cv2.meanStdDev(final_test_1)[0] > cv2.meanStdDev(final_test_2)[0]: box_ctl_final[:,1] = box_ctl_final[:,1]+height final.append(final_test_1) else: box_ctl_final[:,1] = box_ctl_final[:,1]+2*height final.append(final_test_2) cv2.drawContours(image, [box_ctl_final], 0, (0, 0, 255), thickness=2) # Return error message for unclear tests else : print("No Bands Detected") #print(image) #cv2_imshow(image) # generate signal ratio of sample to control band, you can change according to sorting of bands ratio = float(cv2.meanStdDev(final[1])[0] / cv2.meanStdDev(final[0])[0]) thresho = 0.50 sig=(final[1][0]/final[0][0]) #signal=plt.plot(sig,figure=plt.figure()) if ratio >= thresho: xx=str("The test band signal [" + str(ratio) + "] shows a " + target +"-POSITIVE test.") else: xx=str("The test band signal[" + str(ratio) + "] shows a " + target +"-NEGATIVE test.") return xx,figplota(sig),cv2.resize(image, (20,60), interpolation = cv2.INTER_AREA) #cv2.resize(signal, (20,40), interpolation = cv2.INTER_AREA)#,cv2.resize(signal, (20,40), interpolation = cv2.INTER_AREA) iface = gr.Interface(quant, gr.Image(type="filepath"), outputs=["text","plot","image"]) iface.launch()