Design of a gel card reader for blood grouping tests

80 2 0
Design of a gel card reader for blood grouping tests

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

TABLE OF CONTENTS Cover i Mission ii Schedule iii Guarante ix Acknowledgments ixi Table of contents ixii List of figures x List of tables xii Abstract xiiii Chapter INTRODUCTION 1.1 PROBLEM STATEMENT .1 1.2 OBJECTIVE .2 1.3 THESIS CONTENTS .2 1.4 LIMITATIONS 1.5 BRIEF SUMMARY OF THESIS .2 Chapter LITERATURE REVIEW 2.1 TYPES OF HUMAN BLOOD 2.2 GEL CARD METHOD AND TYPE OF GEL CARDS 2.2.1 Gel Card method .5 2.2.2 Type of Gel Cards 2.3 IMAGE PROCESSING ALGORITHM 2.3.1 Dilation method 2.3.2 Edge detection method 2.4 IMAGE CAPTURING DEVICES 2.4.1 Microprocessor introduction 2.4.2 Description of power supply 12 Chapter DESIGN AND CALCULATION 13 3.1 INTRODUCTION 13 3.2 CALCULATION AND DESIGN 13 3.2.1 Block Diagram Of An Capturing Device .13 3.2.2 Image Capturing Device .14 x 3.2.3 Central Processing Unit 14 3.2.4 Image Display and Peripherals .15 3.2.5 Calculation of Power Supply 15 3.2.6 Case designs for the Gel Card Reader 25 3.3 DEVICE CONNECTION .27 3.4 FLOWCHART AND PROGRAM ALGORITHM 28 3.4.1 Functional summary of Gel Card Reader .28 3.4.2 Flowchart 28 3.4.3 A flowchart of agglutination level and blood type .29 3.5 PRINCIPLE OF OPERATION 36 Chapter CONNECTION OF SYSYTEM PARTS 37 4.1 INTRODUCTION 37 4.2 POWER SUPPLY 37 4.2.1 Assembly of the Power Supply 37 4.2.2 Execution of The Power Supply 37 4.2.3 Inspection of The Power Supply 40 4.3 EXECUTION THE CASE OF GEL CARD READER 41 4.4 SYSTEM CONSTRUCTION 41 4.4.1 User Interfere Design 41 4.4.2 Model Construction 42 4.5 PROGRAMMING SOFTWARE 42 4.5.1 Python Programming Software 42 4.5.2 Image processing program 43 4.5.3 QT Designer 44 Chapter RESULTS AND DISCUSSION 46 5.1 GENERAL RESULTS 46 5.2 ACHIEVEMENT RESULTS 46 5.2.1 Power Supply 46 5.2.2 GUI .49 5.2.3 System modelling result .50 5.2.4 Test results 50 5.2.5 Result of Gel Card Reader 51 5.2.6 Actual Results .54 5.3 INSTRUCTION 55 viii 5.4 DISCUSSIONS .56 5.4.1 Advantages 56 5.4.2 Disadvantages .56 Chapter FUTURE WORKS AND CONCLUSION 57 6.1 CONCLUSION .57 6.2 FUTURE WORKS 57 REFERENCES APPENDIX ix LIST OF FIGURES Figure Page Figure The ABO blood grouping system (Source: Wikipedia) Figure 2 Gel Card and parts inside the Gel Card tube Figure Interpretation of results Figure Sample of Forward grouping Gel Card Figure Dilation in image processing (Source: www.cs.auckland.nz) Figure Raspberry Pi 4B (Source: www.deskmodder.de) 11 Figure Block diagram of the system 13 Figure Webcam Hoco D101 14 Figure 3 Block diagram of the switching power supply 16 Figure Schematic of noise filter and primary voltage rectifier circuit 20 Figure Schematic of pulse generator circuit .22 Figure Schematic of secondary voltage rectifier circuit 23 Figure Schematic of secondary voltage feedback circuit 24 Figure Schematic of switching power supply circuit 25 Figure Frontside (a) and backside (b) of the base holder 26 Figure 10 The frontside (a) and backside (b) of the Gel Card Reader case 27 Figure 11 The connection of the entire project Interpret connection diagrams 27 Figure 12 Flowchart of Gel Card Reader system 29 Figure 13 A flowchart of agglutination level and blood type 30 Figure 14 Image area is cropped in Gel Card (red border) 31 Figure 15 The result after image cutting in Gel Card Reader 31 Figure 16 RGB to HSV diagram 32 Figure 17 Results after converted image from RGB to HSV 32 Figure 18 The selectable color threshold for filtering 32 Figure 19 Image after processed with threshold 33 Figure 20 Determine binary image area and draw contour .34 Figure 21 The value belong x and y axis of center point in binary image 34 Figure 22 Flowchart of blood type determination in Gel Card Reader .35 Figure The top side (a) and bottom side (b) of PCB 39 Figure The Volt switching power supply .39 x Figure The inspection output voltage of power supply board 40 Figure 4 Base holder (a) and case (b) of Gel Card Reader 41 Figure Graphic User Interface of Gel Card Reader 42 Figure PyCharm IDE for python programming 43 Figure Gel Card GUI is built on QT Designer 45 Figure Input, output jacks of the switching power supply 47 Figure Measure output voltage when the load is connected 48 Figure GUI of a Gel Card Reader .49 Figure Gel Card Reader system 50 Figure 5 Sample is put into Gel Card Reader 51 Figure The Result interpretation .52 Figure Wrong Gel Card recognition 52 Figure The result interpretation (Sample 1: O- ; Sample 2: B+) 53 Figure The result interpretation (Sample 1: A+ ; Sample 2: B-) 53 Figure 10 DG Reader of GRIFOLS .54 Figure 11 Gel Card Reader and GRIFOLS’s DG Reader Comparison .55 xi LIST OF TABLES Table Page Table Raspberry Pi all generations comparison 11 Table The consumption power of the circuit 15 Table Electronic component of the input filter and rectifier circuit 20 Table 3 Electronic component of pulse generating circuit 21 Table Electronic component of secondary voltage rectifier circuit 23 Table Electronic component of secondary voltage feedback circuits .24 Table Electronic component of the switching power supply board 37 Table Outputs/Inputs voltage of power supply testing .48 Table The Accuracy and Efficiency of Gel Card Reader ………………….…54 xii ABSTRACT Subject "Design of a Gel Card Reader for blood grouping tests." will have the function of reading Gel Card in the blood group test, identifying faulty Card and managing patient information Here use a unique feature, agglutination of the gel columns, to calculate the results Results of the project have identified Gel Card in different blood types and have high accuracy First, the Gel Card image will be captured by the camera after manipulating the user interface The data is then transferred to the Raspberry Pi 4B for image processing for input processing and result computation The results will be displayed on the user interface Also, the system has the function of saving results to manage patient information xiii CHAPTER INTRODUCTION Chapter INTRODUCTION 1.1 PROBLEM STATEMENT Health plays a vital role in our lives Now blood testing has become an important area, including biochemical testing, hematology, blood clotting, and blood grouping It detects early signs of abnormalities in the blood and tends to treat promptly From centuries ago, the discovery of inadequacies in blood transfusion prompted scientists to find the reason for not transfusing blood from person to person In 1901, Karl Landsteiner, who is an Austrian doctor, an essential individual in blood transfusion, for the first time discovered three human blood types A, B and O One year later, the 4th blood type (AB) recorded by A Decastrello and A Sturli More than 40 years later, a factor considered to be the leading cause of blood transfusion reactions (Rh factor) was discovered by Karl Landsteiner, Alex Wiener, Philip Levine and RE Stetson Along with the ABO blood type system, the Rh factor is seen as a breakthrough in blood banking [1] In the last century, the blood grouping test consisted of two main methods: testing on enamel slabs and in vitro These methods have the advantage of being simple, easy to manipulate, cheap in price but have the disadvantage of easy technical errors and confusion in administrative procedures, depending on the user's skills and qualifications In 1988, Dr Yves Lapierre developed Gel technology in blood grouping to minimize the problems occurring compared with the old method The Gel Card is considered the most popular form to be the most effective in blood grouping in hospitals, clinics and laboratories [2] A Gel Card Reader was invented and used to determine the blood grouping Currently, hospitals in Vietnam and around the world are using this device However, A Gel Card Reader presently is distributed in Vietnam is not less than 5000 USD Therefore, the idea of researching and manufacturing a Gel Card Reader with a similar blood group determination function but with a much lower price will significantly contribute to the field of medical tests For the above reasons, the group decided to implement the graduation thesis “Design of a Gel Card Reader for blood grouping tests.” The Gel Card Reader uses a camera to take pictures of the Gel Card containing the treated blood The camera will send a Gel Card image to a central DEPARTMENT OF ELECTRONIC – BIOMEDICAL ENGINEERING CHAPTER INTRODUCTION processing unit The central processor will use an image processing algorithm programmed to process the Gel Card image and produce the defined blood group results 1.2 OBJECTIVE This project aims to create a system that can read the Gel Card for classifying blood group In particular, this system consists of a Raspberry Pi 4B, a camera, a screen and algorithms of image processing 1.3 THESIS CONTENTS ● CONTENT 1: Research on blood group system, Gel Card method ● CONTENT 2: Research the functions of Gel Card Reader ● CONTENT 3: Design flowchart, write the code for image processing ● CONTENT 4: Designing a power supply for Gel Card Reader ● CONTENT 5: Designing a case for Gel Card Reader ● CONTENT 6: Design a graphical user interface (GUI) for the system ● CONTENT 7: Execute the system, evaluate the results, compare with similar equipment, re-evaluate the advantages and disadvantages ● CONTENT 8: Write a thesis report 1.4 LIMITATIONS ● No results will be saved in the event of a power failure ● Card Reader only reads with popular Cel Cards as Forward, Forward and Reverse, CrossMatch, Coombs ● The instrument does not recognize the type of Gel Cards through the barc1.5 BRIEF SUMMARY OF THESIS  Chapter 1: Introduction This chapter shows the Gel Card method's importance, point out the topic's limitations, goals, and make lists  Chapter 2: Materials and methods This chapter describes the theoretical basis of “Design of a Gel Card Reader for blood grouping tests” and the model's working principle  Chapter 3: Design and Calculation DEPARTMENT OF ELECTRONIC – BIOMEDICAL ENGINEERING CHAPTER INTRODUCTION This chapter presents to choose the components and learn how to connect them, and suggest the system's design method  Chapter 4: Connection of system parts This chapter shows how the system is executed and applied to the image processing method  Chapter 5: Result and discussion This chapter discusses the results achieved after completing the system, commenting on the results achieved  Chapter 6: Conclusion and future works This chapter shows the conclusion about the things that we complete, not complete and some drawbacks Present the plan of the topic in the future DEPARTMENT OF ELECTRONIC – BIOMEDICAL ENGINEERING APPENDIX APPENDIX THE CODE OF MAIN PROGRAM from PyQt5 import QtCore from PyQt5 import QtGui from PyQt5.QtCore import pyqtSlot from PyQt5.QtGui import QImage, QPixmap from PyQt5.QtWidgets import QMainWindow, QApplication, QFileDialog, QMessageBox, QLabel, QTextEdit, QWidget, QVBoxLayout from PyQt5.QtGui import QPixmap from PyQt5.QtGui import QTextCursor from PyQt5.QtPrintSupport import QPrintDialog, QPrinter from PyQt5.uic import loadUi from butterworth import Butter import sys import cv2 import numpy as np import scipy.signal as sig import scipy.ndimage as ndi import matplotlib.pyplot as plt class LoadQt(QMainWindow): def init (self): super(LoadQt, self). init () loadUi('thesis1.ui', self) self.setWindowIcon(QtGui.QIcon("python-icon.png")) mainLayout = QVBoxLayout() self.image = None self.pushButton.clicked.connect(self.open_img) #self.actionOpen.triggered.connect(self.open_img) self.actionAuthor.triggered.connect(self.AboutMessage2) self.actionQT_Designer.triggered.connect(self.AboutMessage) self.actionView_Result.triggered.connect(self.AboutMessage2) self.textEdit_2 = QTextEdit() self.label_8.setStyleSheet("background-image: url(:/newPrefix/logo-news.png);") self.setLayout(mainLayout) @pyqtSlot() def loadImage(self, fname): self.image = cv2.imread(fname) self.tmp = self.image self.displayImage(fname) self.ReadGelcard() def Giaodien(self): fname, filter = QFileDialog.getOpenFileName(self, 'Open File', 'C:/Users/Admin/Desktop/gelcard/Image-Processing-with-OpenCV-Python-and-PyQt5master/tải xuống.png',) if fname: self.loadImage(fname) else: print("Invalid Image") DEPARTMENT OF ELECTRONIC – BIOMEDICAL ENGINEERING APPENDIX def displayImage(self, window=1): qformat = QImage.Format_Indexed8 if len(self.image.shape) == 3: if (self.image.shape[2]) == 4: qformat = QImage.Format_RGBA8888 else: qformat = QImage.Format_RGB888 img = QImage(self.image, self.image.shape[1], self.image.shape[0], qformat) img = img.rgbSwapped() self.label_9.setPixmap(QPixmap.fromImage(img)) # serPixmap setPixmap self.label_9.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) def open_img(self): fname, filter = QFileDialog.getOpenFileName(self, 'Open File', 'C:\\Users\DELL\PycharmProjects\DemoPro', "Image Files (*)") if fname: self.loadImage(fname) else: print("Invalid Image") # cap = cv2.VideoCapture(0) # ret, frame = cap.read() # self.displayImage(frame, 1) # self.displayImage(frame, 1) # cap.release() # cv2.destroyAllWindows() def save_img(self): fname, filter = QFileDialog.getSaveFileName(self, 'Save File', 'C:\\', "Image Files (*.png)") if fname: cv2.imwrite(fname, self.image) # Lưu trữ ảnh print("Error") def AboutMessage(self): QMessageBox.about(self, "About Qt - Qt Designer", "Qt is a multiplatform C + + GUI toolkit created and maintained byTrolltech.It provides application developers with all the functionality needed to build applications with state-of-the-art graphical user interfaces.\n" "Qt is fully object-oriented, easily extensible, and allows true component programming.Read the Whitepaper for a comprehensive technical overview.\n\n" "Since its commercial introduction in early 1996, Qt has formed the basis of many thousands of successful applications worldwide.Qt is also the basis of the popular KDE Linux desktop environment, a standard component of all major Linux distributions.See our Customer Success Stories for some examples of commercial Qt development.\n\n" "Qt is supported on the following platforms:\n\n" "\tMS / Windows - - 95, 98, NT\n" DEPARTMENT OF ELECTRONIC – BIOMEDICAL ENGINEERING APPENDIX "\t4.0, ME, 2000, and XP\n" "\tUnix / X11 - - Linux, Sun\n" "\tSolaris, HP - UX, Compaq Tru64 UNIX, IBM AIX, SGI IRIX and a wide range of others\n" "\tMacintosh - - Mac OS X\n" "\tEmbedded - - Linux platforms with framebuffer support.\n\n" "Qt is released in different editions:\n\n" "\tThe Qt Enterprise Edition and the Qt Professional Edition provide for commercial software development.They permit traditional commercial software distribution and include free upgrades and Technical Support.For the latest prices, see the Trolltech web site, Pricing and Availability page, or contact sales @ trolltech.com.The Enterprise Edition offers additional modules compared to the Professional Edition.\n\n" "\tThe Qt Open Source Edition is available for Unix / X11, Macintosh and Embedded Linux.The Open Source Edition is for the development of Free and Open Source software only.It is provided free of charge under the terms of both the Q Public License and the GNU General Public License." ) def AboutMessage2(self): QMessageBox.about(self, "About Author", "Lecturer: Assoc Prof Dr Nguyen Thanh Hai \n\n" "Student:\n" "\tNguyen Minh Duc - ID: 16129017 " "\t Truong Hoang Gia Bao - ID: 16129007" ) def QuestionMessage(self): message = QMessageBox.question(self, "Exit", "Bạn có muốn thoát", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if message == QMessageBox.Yes: print("Yes") self.close() else: print("No") def ReadGelcard(self): roi1 = self.image[274:274 + 255, 423:423 + 75] roi2 = self.image[274:274 + 255, 564:564 + 75] roi3 = self.image[274:274 + 255, 708:708 + 75] roi4 = self.image[274:274 + 255, 855:855 + 75] roi5 = self.image[274:274 + 255, 1002:1002 + 75] roi6 = self.image[274:274 + 255, 1145:1145 + 75] roi7 = self.image[274:274 + 255, 1289:1289 + 75] roi8 = self.image[274:274 + 255, 1427:1427 + 75] roi1 = cv2.resize(roi1, None, fx=0.5, fy=0.5) hsv1 = cv2.cvtColor(roi1, cv2.COLOR_BGR2HSV) roi2 = cv2.resize(roi2, None, fx=0.5, fy=0.5) hsv2 = cv2.cvtColor(roi2, cv2.COLOR_BGR2HSV) roi3 = cv2.resize(roi3, None, fx=0.5, fy=0.5) hsv3 = cv2.cvtColor(roi3, cv2.COLOR_BGR2HSV) DEPARTMENT OF ELECTRONIC – BIOMEDICAL ENGINEERING APPENDIX roi4 = cv2.resize(roi4, None, fx=0.5, fy=0.5) hsv4 = cv2.cvtColor(roi4, cv2.COLOR_BGR2HSV) roi5 = cv2.resize(roi5, None, fx=0.5, fy=0.5) hsv5 = cv2.cvtColor(roi5, cv2.COLOR_BGR2HSV) roi6 = cv2.resize(roi6, None, fx=0.5, fy=0.5) hsv6 = cv2.cvtColor(roi6, cv2.COLOR_BGR2HSV) roi7 = cv2.resize(roi7, None, fx=0.5, fy=0.5) hsv7 = cv2.cvtColor(roi7, cv2.COLOR_BGR2HSV) roi8 = cv2.resize(roi8, None, fx=0.5, fy=0.5) hsv8 = cv2.cvtColor(roi8, cv2.COLOR_BGR2HSV) # mask microtube lower_red = np.array([0, 70, 50]) upper_red = np.array([10, 255, 255]) mask1 = cv2.inRange(hsv1, lower_red, upper_red) lower_red = np.array([170, 70, 50]) upper_red = np.array([180, 255, 255]) mask2 = cv2.inRange(hsv1, lower_red, upper_red) mask = mask1 + mask2 output1 = cv2.bitwise_and(hsv1, roi1, mask=mask) gray1 = cv2.cvtColor(output1, cv2.COLOR_RGB2GRAY) ret, threshold1 = cv2.threshold(gray1, 10, 255, 0) kernel = np.ones((5, 5), np.uint8) dilation1 = cv2.dilate(threshold1, kernel, iterations=1) contours, hierarchy = cv2.findContours(dilation1, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) total_contours = len(contours) print('Phat hien: ', total_contours) locations = [] for contour in contours: M = cv2.moments(contour) cX = int(M["m10"] / M["m00"]) cY = int(M["m01"] / M["m00"]) print('Tam theo truc x:', cX, ' Tam theo truc y', cY) locations.append([cX, cY]) def takeFirst(elem): return elem[0] locations.sort(key=takeFirst) stringState = [] for location in locations: indexY = location[1] indexX = location[0] if indexY < 60: DEPARTMENT OF ELECTRONIC – BIOMEDICAL ENGINEERING APPENDIX cv2.circle(roi1, (indexX, indexY), 3, (255, 255, 255), -1) stringState.append('Duong tinh (4+)') kq1 = self.textBrowser_3.setText('Positive (4+)') elif indexY > 60 and indexY < 70: cv2.circle(roi1, (indexX, indexY), 3, (255, 255, 255), -1) stringState.append('Duong tinh (3+)') kq1 = self.textBrowser_3.setText('Positive (3+)') elif indexY > 70 and indexY < 80: cv2.circle(roi1, (indexX, indexY), 3, (255, 255, 255), -1) stringState.append('Duong tinh (2+)') kq1 = self.textBrowser_3.setText('Positive (2+)') elif indexY > 80 and indexY < 95: cv2.circle(roi1, (indexX, indexY), 3, (255, 255, 255), -1) stringState.append('Duong tinh (1+)') kq1 = self.textBrowser_3.setText('Positive (1+)') else: cv2.circle(roi1, (indexX, indexY), 3, (0, 0, 0), -1) stringState.append('Am tinh (-)') kq1 = self.textBrowser_3.setText('Negative (-)') # mask microtube lower_red = np.array([0, 70, 50]) upper_red = np.array([10, 255, 255]) mask1 = cv2.inRange(hsv2, lower_red, upper_red) lower_red = np.array([170, 70, 50]) upper_red = np.array([180, 255, 255]) mask2 = cv2.inRange(hsv2, lower_red, upper_red) mask = mask1 + mask2 output = cv2.bitwise_and(hsv2, roi2, mask=mask) gray2 = cv2.cvtColor(output, cv2.COLOR_RGB2GRAY) ret, threshold2 = cv2.threshold(gray2, 10, 255, 0) kernel = np.ones((5, 5), np.uint8) dilation2 = cv2.dilate(threshold2, kernel, iterations=1) contours, hierarchy = cv2.findContours(dilation2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) total_contours = len(contours) print('Phat hien: ', total_contours) locations = [] for contour in contours: M = cv2.moments(contour) cX = int(M["m10"] / M["m00"]) cY = int(M["m01"] / M["m00"]) print('Tam theo truc x:', cX, ' Tam theo truc y', cY) DEPARTMENT OF ELECTRONIC – BIOMEDICAL ENGINEERING APPENDIX locations.append([cX, cY]) def takeFirst(elem): return elem[0] locations.sort(key=takeFirst) stringState = [] for location in locations: indexY = location[1] indexX = location[0] if indexY < 60: cv2.circle(roi2, (indexX, indexY), 3, (255, 255, 255), -1) stringState.append('Duong tinh (4+)') kq2 = self.textBrowser_4.setText('Positive (4+)') elif indexY > 60 and indexY < 70: cv2.circle(roi2, (indexX, indexY), 3, (255, 255, 255), -1) stringState.append('Duong tinh (3+)') kq2 = self.textBrowser_4.setText('Positive (3+)') elif indexY > 70 and indexY < 80: cv2.circle(roi2, (indexX, indexY), 3, (255, 255, 255), -1) stringState.append('Duong tinh (2+)') kq2 = self.textBrowser_4.setText('Positive (2+)') elif indexY > 80 and indexY < 95: cv2.circle(roi2, (indexX, indexY), 3, (255, 255, 255), -1) stringState.append('Duong tinh (1+)') kq2 = self.textBrowser_4.setText('Positive (1+)') else: cv2.circle(roi2, (indexX, indexY), 3, (0, 0, 0), -1) stringState.append('Am tinh (-)') kq2 = self.textBrowser_4.setText('Negative (-)') # mask microtube lower_red = np.array([0, 70, 50]) upper_red = np.array([10, 255, 255]) mask1 = cv2.inRange(hsv3, lower_red, upper_red) lower_red = np.array([170, 70, 50]) upper_red = np.array([180, 255, 255]) mask2 = cv2.inRange(hsv3, lower_red, upper_red) mask = mask1 + mask2 output3 = cv2.bitwise_and(hsv3, roi3, mask=mask) gray3 = cv2.cvtColor(output3, cv2.COLOR_RGB2GRAY) ret, threshold3 = cv2.threshold(gray3, 10, 255, 0) kernel = np.ones((5, 5), np.uint8) DEPARTMENT OF ELECTRONIC – BIOMEDICAL ENGINEERING APPENDIX dilation3 = cv2.dilate(threshold3, kernel, iterations=1) contours, hierarchy = cv2.findContours(dilation3, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) total_contours = len(contours) print('Phat hien: ', total_contours) locations = [] for contour in contours: M = cv2.moments(contour) cX = int(M["m10"] / M["m00"]) cY = int(M["m01"] / M["m00"]) print('Tam theo truc x:', cX, ' Tam theo truc y', cY) locations.append([cX, cY]) def takeFirst(elem): return elem[0] locations.sort(key=takeFirst) stringState = [] for location in locations: indexY = location[1] indexX = location[0] if indexY < 60: cv2.circle(roi3, (indexX, indexY), 3, (255, 255, 255), -1) stringState.append('Duong tinh (4+)') kq3 = self.textBrowser_5.setText('Positive (4+)') elif indexY > 60 and indexY < 70: cv2.circle(roi3, (indexX, indexY), 3, (255, 255, 255), -1) stringState.append('Duong tinh (3+)') kq3 = self.textBrowser_5.setText('Positive (3+)') elif indexY > 70 and indexY < 80: cv2.circle(roi3, (indexX, indexY), 3, (255, 255, 255), -1) stringState.append('Duong tinh (2+)') kq3 = self.textBrowser_5.setText('Positive (2+)') elif indexY > 80 and indexY < 95: cv2.circle(roi3, (indexX, indexY), 3, (255, 255, 255), -1) stringState.append('Duong tinh (1+)') kq3 = self.textBrowser_5.setText('Positive (1+)') else: cv2.circle(roi3, (indexX, indexY), 3, (0, 0, 0), -1) stringState.append('Am tinh (-)') kq3 = self.textBrowser_5.setText('Negative (-)') # mask microtube lower_red = np.array([0, 70, 50]) upper_red = np.array([10, 255, 255]) DEPARTMENT OF ELECTRONIC – BIOMEDICAL ENGINEERING APPENDIX mask1 = cv2.inRange(hsv4, lower_red, upper_red) lower_red = np.array([170, 70, 50]) upper_red = np.array([180, 255, 255]) mask2 = cv2.inRange(hsv4, lower_red, upper_red) mask = mask1 + mask2 output4 = cv2.bitwise_and(hsv4, roi4, mask=mask) gray4 = cv2.cvtColor(output4, cv2.COLOR_RGB2GRAY) ret, threshold4 = cv2.threshold(gray4, 10, 255, 0) kernel = np.ones((5, 5), np.uint8) dilation4 = cv2.dilate(threshold4, kernel, iterations=1) contours, hierarchy = cv2.findContours(dilation4, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) total_contours = len(contours) print('Phat hien: ', total_contours) locations = [] for contour in contours: M = cv2.moments(contour) cX = int(M["m10"] / M["m00"]) cY = int(M["m01"] / M["m00"]) print('Tam theo truc x:', cX, ' Tam theo truc y', cY) locations.append([cX, cY]) def takeFirst(elem): return elem[0] locations.sort(key=takeFirst) stringState = [] for location in locations: indexY = location[1] indexX = location[0] if indexY < 60: cv2.circle(roi4, (indexX, indexY), 3, (255, 255, 255), -1) stringState.append('Duong tinh (4+)') kq4 = self.textBrowser_9.setText('Positive (4+)') elif indexY > 60 and indexY < 70: cv2.circle(roi4, (indexX, indexY), 3, (255, 255, 255), -1) stringState.append('Duong tinh (3+)') kq4 = self.textBrowser_9.setText('Positive (3+)') elif indexY > 70 and indexY < 80: cv2.circle(roi4, (indexX, indexY), 3, (255, 255, 255), -1) stringState.append('Duong tinh (2+)') kq4 = self.textBrowser_9.setText('Positive (2+)') DEPARTMENT OF ELECTRONIC – BIOMEDICAL ENGINEERING APPENDIX elif indexY > 80 and indexY < 95: cv2.circle(roi4, (indexX, indexY), 3, (255, 255, 255), -1) stringState.append('Duong tinh (1+)') kq4 = self.textBrowser_9.setText('Positive (1+)') else: cv2.circle(roi4, (indexX, indexY), 3, (0, 0, 0), -1) stringState.append('Am tinh (-)') kq4 = self.textBrowser_9.setText('Negative (-)') # mask microtube lower_red = np.array([0, 70, 50]) upper_red = np.array([10, 255, 255]) mask1 = cv2.inRange(hsv5, lower_red, upper_red) lower_red = np.array([170, 70, 50]) upper_red = np.array([180, 255, 255]) mask2 = cv2.inRange(hsv5, lower_red, upper_red) mask = mask1 + mask2 output5 = cv2.bitwise_and(hsv5, roi5, mask=mask) gray5 = cv2.cvtColor(output5, cv2.COLOR_RGB2GRAY) ret, threshold5 = cv2.threshold(gray5, 10, 255, 0) kernel = np.ones((5, 5), np.uint8) dilation5 = cv2.dilate(threshold5, kernel, iterations=1) contours, hierarchy = cv2.findContours(dilation5, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) total_contours = len(contours) print('Phat hien: ', total_contours) locations = [] for contour in contours: M = cv2.moments(contour) cX = int(M["m10"] / M["m00"]) cY = int(M["m01"] / M["m00"]) print('Tam theo truc x:', cX, ' Tam theo truc y', cY) locations.append([cX, cY]) def takeFirst(elem): return elem[0] locations.sort(key=takeFirst) stringState = [] for location in locations: indexY = location[1] indexX = location[0] if indexY < 60: cv2.circle(roi5, (indexX, indexY), 3, (255, 255, 255), -1) DEPARTMENT OF ELECTRONIC – BIOMEDICAL ENGINEERING APPENDIX stringState.append('Duong tinh (4+)') kq5 = self.textBrowser_10.setText('Positive (4+)') elif indexY > 60 and indexY < 70: cv2.circle(roi5, (indexX, indexY), 3, (255, 255, 255), -1) stringState.append('Duong tinh (3+)') kq5 = self.textBrowser_10.setText('Positive (3+)') elif indexY > 70 and indexY < 80: cv2.circle(roi5, (indexX, indexY), 3, (255, 255, 255), -1) stringState.append('Duong tinh (2+)') kq5 = self.textBrowser_10.setText('Positive (2+)') elif indexY > 80 and indexY < 95: cv2.circle(roi5, (indexX, indexY), 3, (255, 255, 255), -1) stringState.append('Duong tinh (1+)') kq5 = self.textBrowser_10.setText('Positive (1+)') else: cv2.circle(roi5, (indexX, indexY), 3, (0, 0, 0), -1) stringState.append('Am tinh (-)') kq5 = self.textBrowser_10.setText('Negative (-)') # mask microtube lower_red = np.array([0, 70, 50]) upper_red = np.array([10, 255, 255]) mask1 = cv2.inRange(hsv6, lower_red, upper_red) lower_red = np.array([170, 70, 50]) upper_red = np.array([180, 255, 255]) mask2 = cv2.inRange(hsv6, lower_red, upper_red) mask = mask1 + mask2 output6 = cv2.bitwise_and(hsv6, roi6, mask=mask) gray6 = cv2.cvtColor(output6, cv2.COLOR_RGB2GRAY) ret, threshold6 = cv2.threshold(gray6, 10, 255, 0) kernel = np.ones((5, 5), np.uint8) dilation6 = cv2.dilate(threshold6, kernel, iterations=1) contours, hierarchy = cv2.findContours(dilation6, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) total_contours = len(contours) print('Phat hien: ', total_contours) locations = [] for contour in contours: M = cv2.moments(contour) cX = int(M["m10"] / M["m00"]) cY = int(M["m01"] / M["m00"]) print('Tam theo truc x:', cX, ' Tam theo truc y', cY) locations.append([cX, cY]) DEPARTMENT OF ELECTRONIC – BIOMEDICAL ENGINEERING APPENDIX def takeFirst(elem): return elem[0] locations.sort(key=takeFirst) stringState = [] for location in locations: indexY = location[1] indexX = location[0] if indexY < 60: cv2.circle(roi6, (indexX, indexY), 3, (255, 255, 255), -1) stringState.append('Duong tinh (4+)') kq6 = self.textBrowser_8.setText('Positive (4+)') elif indexY > 60 and indexY < 70: cv2.circle(roi6, (indexX, indexY), 3, (255, 255, 255), -1) stringState.append('Duong tinh (3+)') kq6 = self.textBrowser_8.setText('Positive (3+)') elif indexY > 70 and indexY < 80: cv2.circle(roi6, (indexX, indexY), 3, (255, 255, 255), -1) stringState.append('Duong tinh (2+)') kq6 = self.textBrowser_8.setText('Positive (2+)') elif indexY > 80 and indexY < 95: cv2.circle(roi6, (indexX, indexY), 3, (255, 255, 255), -1) stringState.append('Duong tinh (1+)') kq6 = self.textBrowser_8.setText('Positive (1+)') else: cv2.circle(roi6, (indexX, indexY), 3, (0, 0, 0), -1) stringState.append('Am tinh (-)') kq6 = self.textBrowser_8.setText('Negative (-)') # mask microtube lower_red = np.array([0, 26, 141]) upper_red = np.array([179, 255, 255]) mask1 = cv2.inRange(hsv7, lower_red, upper_red) lower_red = np.array([0, 26, 141]) upper_red = np.array([179, 255, 255]) mask = mask1 + mask2 output7 = cv2.bitwise_and(hsv7, roi7, mask=mask) gray7 = cv2.cvtColor(output7, cv2.COLOR_RGB2GRAY) ret, threshold7 = cv2.threshold(gray7, 10, 255, 0) kernel = np.ones((5, 5), np.uint8) dilation7 = cv2.dilate(threshold7, kernel, iterations=1) contours, hierarchy = cv2.findContours(dilation7, cv2.RETR_TREE, DEPARTMENT OF ELECTRONIC – BIOMEDICAL ENGINEERING APPENDIX cv2.CHAIN_APPROX_SIMPLE) total_contours = len(contours) print('Phat hien: ', total_contours) locations = [] for contour in contours: M = cv2.moments(contour) cX = int(M["m10"] / M["m00"]) cY = int(M["m01"] / M["m00"]) print('Tam theo truc x:', cX, ' Tam theo truc y', cY) locations.append([cX, cY]) def takeFirst(elem): return elem[0] locations.sort(key=takeFirst) stringState = [] for location in locations: indexY = location[1] indexX = location[0] if indexY < 60: cv2.circle(roi7, (indexX, indexY), 3, (255, 255, 255), -1) stringState.append('Duong tinh (4+)') kq7 = self.textBrowser_6.setText('Positive (4+)') elif indexY > 60 and indexY < 70: cv2.circle(roi7, (indexX, indexY), 3, (255, 255, 255), -1) stringState.append('Duong tinh (3+)') kq7 = self.textBrowser_6.setText('Positive (3+)') elif indexY > 70 and indexY < 80: cv2.circle(roi7, (indexX, indexY), 3, (255, 255, 255), -1) stringState.append('Duong tinh (2+)') kq7 = self.textBrowser_6.setText('Positive (2+)') elif indexY > 80 and indexY < 95: cv2.circle(roi7, (indexX, indexY), 3, (255, 255, 255), -1) stringState.append('Duong tinh (1+)') kq7 = self.textBrowser_6.setText('Positive (1+)') else: cv2.circle(roi7, (indexX, indexY), 3, (0, 0, 0), -1) stringState.append('Am tinh (-)') kq7 = self.textBrowser_6.setText('Negative (-)') # mask microtube lower_red = np.array([0, 70, 50]) upper_red = np.array([10, 255, 255]) mask1 = cv2.inRange(hsv8, lower_red, upper_red) lower_red = np.array([170, 70, 50]) DEPARTMENT OF ELECTRONIC – BIOMEDICAL ENGINEERING APPENDIX upper_red = np.array([180, 255, 255]) mask2 = cv2.inRange(hsv8, lower_red, upper_red) mask = mask1 + mask2 output8 = cv2.bitwise_and(hsv8, roi8, mask=mask) gray8 = cv2.cvtColor(output8, cv2.COLOR_RGB2GRAY) ret, threshold8 = cv2.threshold(gray8, 10, 255, 0) kernel = np.ones((5, 5), np.uint8) dilation8 = cv2.dilate(threshold8, kernel, iterations=1) contours, hierarchy = cv2.findContours(dilation8, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) total_contours = len(contours) print('Phat hien: ', total_contours) locations = [] for contour in contours: M = cv2.moments(contour) cX = int(M["m10"] / M["m00"]) cY = int(M["m01"] / M["m00"]) print('Tam theo truc x:', cX, ' Tam theo truc y', cY) locations.append([cX, cY]) def takeFirst(elem): return elem[0] locations.sort(key=takeFirst) stringState = [] for location in locations: indexY = location[1] indexX = location[0] if indexY < 60: cv2.circle(roi8, (indexX, indexY), 3, (255, 255, 255), -1) stringState.append('Duong tinh (4+)') kq8 = self.textBrowser_7.setText('Positive (4+)') elif indexY > 60 and indexY < 70: cv2.circle(roi8, (indexX, indexY), 3, (255, 255, 255), -1) stringState.append('Duong tinh (3+)') kq8 = self.textBrowser_7.setText('Positive (3+)') elif indexY > 70 and indexY < 80: cv2.circle(roi8, (indexX, indexY), 3, (255, 255, 255), -1) stringState.append('Duong tinh (2+)') kq8 = self.textBrowser_7.setText('Positive (2+)') elif indexY > 80 and indexY < 95: cv2.circle(roi8, (indexX, indexY), 3, (255, 255, 255), -1) stringState.append('Duong tinh (1+)') DEPARTMENT OF ELECTRONIC – BIOMEDICAL ENGINEERING APPENDIX kq8 = self.textBrowser_7.setText('Positive (1+)') else: cv2.circle(roi8, (indexX, indexY), 3, (0, 0, 0), -1) stringState.append('Am tinh (-)') kq8 = self.textBrowser_7.setText('Negative (-)') if kq4 == and kq8 == 0: if (kq1 > 1) and (kq2 > 1) and kq3 > 1: print("Sample 1, Blood group: (AB+)") self.textBrowser.setText('Sample 1, Blood group: (AB+)') elif (kq1 > 0) and (kq2 > 0) and kq3 == 0: print("Sample 1, Blood group: (AB-)") self.textBrowser.setText('Sample 1, Blood group: (AB-)') elif kq1 == and kq2 > and kq3 > 0: print("Sample 1, Blood group: (B+)") self.textBrowser.setText('Sample 1, Blood group: (B+)') elif kq1 == and kq2 > and kq3 == 0: print("Sample 1, Blood group: (B-)") self.textBrowser.setText('Sample 1, Blood group: (B-)') elif kq1 > and kq2 == and kq3 > 0: print("Sample 1, Blood group: (A+)") self.textBrowser.setText('Sample 1, Blood group: (A+)') elif kq1 > and kq2 == and kq3 == 0: print("Sample 1, Blood group: (A-)") self.textBrowser.setText('Sample 1, Blood group: (A-)') elif kq1 == and kq2 == and kq3 > 0: print("Sample 1, Blood group: (O+)"); self.textBrowser.setText('Sample 1, Blood group: (O+)') elif kq1 == and kq2 == and kq3 == 0: print("Sample 1, Blood group: (O-)"); self.textBrowser.setText('Sample 1, Blood group: (O-)') if (kq5 > 1) and (kq6 > 1) and kq7 > 1: print("Sample 2, Blood group: (AB+)") self.textBrowser_2.setText('Sample 2, Blood group: (AB+)') elif (kq5 > 0) and (kq6 > 0) and kq7 == 0: print("Sample 2, Blood group: (AB-)") self.textBrowser_2.setText('Sample 2, Blood group: (AB-)') elif kq5 == and kq6 > and kq7 > 0: print("Sample 2, Blood group: (B+)") self.textBrowser_2.setText('Sample 2, Blood group: (B+)') elif kq5 == and kq6 > and kq7 == 0: print("Sample 2, Blood group: (B-)") self.textBrowser_2.setText('Sample 2, Blood group: (B-)') elif kq5 > and kq6 == and kq7 > 0: print("Sample 2, Blood group: (A+)") self.textBrowser_2.setText('Sample 2, Blood group: (A+)') elif kq5 > and kq6 == and kq7 == 0: print("Sample 2, Blood group: (A-)") self.textBrowser_2.setText('Sample 2, Blood group: (A-)') elif kq5 == and kq6 == and kq7 > 0: print("Sample 2, Blood group: (O+)"); self.textBrowser_2.setText('Sample 2, Blood group: (O+)') elif kq5 == and kq6 == and kq7 == 0: print("Sample 2, Blood group: (O-)"); self.textBrowser_2.setText('Sample 2, Blood group: (O-)') DEPARTMENT OF ELECTRONIC – BIOMEDICAL ENGINEERING APPENDIX else: self.textBrowser.setText('Wrong Gelcard, please use another Gelcard') self.textBrowser_2.setText('Wrong Gelcard, please use another Gelcard') print("Wrong Gelcard, please use another Gelcard") ########################################Moire Pattern########################################################## import hinhanh app = QApplication(sys.argv) win = LoadQt() win.show() sys.exit(app.exec()) DEPARTMENT OF ELECTRONIC – BIOMEDICAL ENGINEERING ... field of medical tests For the above reasons, the group decided to implement the graduation thesis ? ?Design of a Gel Card Reader for blood grouping tests. ” The Gel Card Reader uses a camera to take... "Design of a Gel Card Reader for blood grouping tests. " will have the function of reading Gel Card in the blood group test, identifying faulty Card and managing patient information Here use a unique... negative 2.2.2 Type of Gel Cards a) Forward grouping Gel Card Forward grouping Gel Card has micro tubes, each test uses tubes A, B, D and Ctrl Tube A contains antibodies A, tube B contains antibodies

Ngày đăng: 01/11/2022, 12:49

Tài liệu cùng người dùng

Tài liệu liên quan