Hướng phát triển đề tài

Một phần của tài liệu HỆ THỐNG KIỂM TRA LỖI TRÊN BOARD MẠCH ĐIỆN TỬ (Trang 50 - 70)

Với điều kiện kinh tế còn eo hẹp, kiến thức còn nhiều hạn chế và thời gian thực hiện đề tài gấp rút nên mô hình kiểm tra mạch PCB của em còn nhiều thiếu sót, đặc biệt về tính thẩm mĩ và khả năng tối ưu. Trong tương lai, em mong muốn sẽ tiếp tục cải thiện mô hình ngày một hoàn thiện hơn để có thể ứng dụng vào thực tế. Đặc biệt trong quá trình cải thiện hệ thống ngoài việc nâng cao độ chính xác, em còn mong muốn hệ thống có thể xử lý được nhiều lỗi khó hơn trước sự đã dạng của các mạch PCB nói chung và các loại lỗi xảy ra trong quá trình sản xuất nói riêng. Từ đây có thể giải quyết bài toán kiểm tra bảng mạch một cách đa dạng và linh hoạt hơn nữa. Dưới đây là một số lỗi khó kiểm tra xảy ra trên mạch PCB mà em tìm hiểu được.

Trong quá trình thực hiện đồ án em đã gặp không ít khó khăn trong việc cài đặt thiết bị, lên ý tưởng thực hiện…nhưng với sự nhiệt tình giúp đỡ sinh viên của cô Trần Thị Như Hà, em đã có thể hoàn thành đồ án tốt nghiệp này. Em xin gửi lời cảm ơn chân thành nhất đến thầy và các thầy cô trong ban hội đồng đã hướng dẫn và tạo điều kiện cho em hoàn thiện đồ án tốt nghiệp này một cách tốt nhất.

TÀI LIỆU THAM KHẢO

1. Giáo trình

[1] Trần Hoàn, Trích “ LUẬN VĂN THẠC SĨ”, Trường Đại học Bách khoa TPHCM [2] Abdullah Hasan AlSaadi et al. ,“Analysis of different background subtraction methods applied on Drone imagery under various weather conditions in the UAE region”, Tawazun Technology and Innovation (TTI), Khalifa University, Abu Dhabi, United Arab Emirates.

[3] S. Kolkur et al. ,” Human Skin Detection Using RGB, HSV and YCbCr Color Models”, Department of Computer Engineering, Sardar Patel Institute of Technology, Andheri,Mumbai, India.

2. Trang web

[1] http://hano.cf/ (trang hướng dẫn cài đặt opencv + visual + tài liệu)

[3] https://funvision.blogspot.com/ (Trang hướng dẫn xử lý ảnh) [4] https://docs.opencv.org/2.4/index.html

PHỤ LỤC using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using MetroFramework; using Emgu.CV; using Emgu.CV.Structure; using Emgu.CV.Util; using System.IO; using Kiemtramach.ProcessROI; using System.IO.Ports; namespace Kiemtramach {

public partial class Form1 : MetroFramework.Forms.MetroForm {

struct MainImage {

public Image<Bgr, byte> Image; public Mat Mat;

MainImage m_RawImage; Mat m_mFrame; VideoCapture m_Capture; int m_CameraID; Feature_Matching.FTMC m_FTMC; string imgPath;

Image<Bgr, byte> m_MainImg; SerialPort serialPort1;

bool isConnected = false; bool m_bDetectPCB; String[] Ports;

public Form1() {

InitializeComponent();

m_RawImage = new MainImage(); m_RawImage.Mat = new Mat(); m_CameraID = 1;

m_Capture = null; imgPath = @"C:\Temp"; getAvailablePort();

// Cai dat nut nhan cho he thong btnSample.Enabled = true; m_bDetectPCB = false; }

private void btnOpen_Click(object sender, EventArgs e) {

m_FTMC = new Feature_Matching.FTMC(); btnInspection.Enabled = true;

if (cmbSample.Text == "Image") { openImage(ref m_RawImage); } btnSample.Enabled = true; btnInspection.Enabled = false; if (cmbSample.Text == "Camera") { openCamera(); } }

private void btnSample_Click(object sender, EventArgs e) {

// 1. Tam dung camera neu dang mo if (m_Capture != null)

{

m_bDetectPCB = false; m_Capture.Pause(); }

// 2. Lay ROI cua mach PCB

Image<Gray, byte> templatImage = new Image<Gray, byte>(@"C:\Users\Bao Bao\Pictures\Camera Roll\WIN_20210630_01_40_11_Pro.jpg");

VectorOfPoint vp = new VectorOfPoint();

var grayImg = m_RawImage.Image.Convert<Gray, byte>(); m_FTMC.ProcessImage(templatImage, grayImg, ref vp); if (vp != null)

{

// Change Raw Image to ROI Image

m_RawImage.Image.ROI = roi; m_MainImg = m_RawImage.Image.Copy().Clone(); ptbMainImage.Image = m_MainImg.AsBitmap(); CvInvoke.Imwrite(@"C:\Temp\anhMain.jpg", m_MainImg); } btnInspection.Enabled = true; }

private void btnInspection_Click(object sender, EventArgs e) {

if (m_MainImg != null) {

Image<Bgr, byte>[] ImageL = new Image<Bgr, byte>[4]; //Hsv minR = new Hsv(0, 100, 138);

//Hsv maxR = new Hsv(190, 180, 240);

//Image<Bgr, byte> temp = new Image<Bgr, byte>(@"C:\Temp\anhMain.jpg");

////ptbMainImage.Image = temp.ToBitmap(); //int numButton =

ProcessROI.GetRegionProcess.CountComponentContour_HSV(temp, minR, maxR); Image<Bgr, byte>[] lImgs;

Image<Bgr, byte> ImgRegion;

GetRegionProcess(m_MainImg, out ImgRegion, out lImgs); ptbMainImage.Image = ImgRegion.ToBitmap(); if(isConnected) { Send_Data("OK"); } }

}

// Ham phu tro

private void openImage(ref MainImage image_) {

try {

OpenFileDialog fl = new OpenFileDialog(); fl.Filter = "Image|*.bmp;*.jpg;*.png"; fl.Multiselect = false;

if(fl.ShowDialog() == DialogResult.OK) {

image_.Mat = new Mat(fl.FileName);

image_.Image = new Image<Bgr, byte>(fl.FileName); ptbMainImage.Image = new Bitmap(fl.FileName); }

}

catch(Exception ex) {

MessageBox.Show("Lỗi mở ảnh, kiểm tra lại.\n"+ ex.Message); }

return; }

private void openCamera() {

if (m_Capture == null) {

m_Capture = new VideoCapture(1); }

m_mFrame = new Mat();

m_Capture.ImageGrabbed += ProcessFrame; m_Capture.Start();

}

private void ProcessFrame(object sender,EventArgs e) {

try {

m_Capture.Retrieve(m_mFrame,0); m_RawImage.Mat = m_mFrame;

m_RawImage.Image = m_RawImage.Mat.ToImage<Bgr, byte>(); ptbMainImage.Image = m_RawImage.Image.ToBitmap();

if (m_bDetectPCB == true) {

updateMainImageCallBack _mainImage = new updateMainImageCallBack(DetectPCB);

this.Invoke(_mainImage, new object[] { m_RawImage.Image }); }

}

catch (Exception ex) {

Console.WriteLine("Khong the mo camera, kiem tra lai.\n Loi:" + ex.Message);

} }

public delegate void updateMainImageCallBack(Image<Bgr, byte> mainImage); public void DetectPCB(Image<Bgr, byte> _mainImage)

btnSample.PerformClick(); btnInspection.PerformClick(); }

private void GetRegionProcess(Image<Bgr, byte> _Image, out Image<Bgr, byte> Image_, out Image<Bgr, byte>[] Images_)

{

Images_ = new Image<Bgr, byte>[6]; //MCvFont font = new

MCvFont(Emgu.CV.CvEnum.FONT.CV_FONT_HERSHEY_SIMPLEX, 0.3f, 0.3f); Bgr green = new Bgr(0, 255, 0);

// VUNG 0 KIEM TRA THIEU TU DIEN - NGUOC TU DIEN Rectangle region0 = new Rectangle(240, 0, _Image.Width-240,160); _Image.ROI = region0;

Images_[0] = _Image.Copy();

Inspection.CountComponentContour(Images_[0], out Images_[0]); _Image.ROI = Rectangle.Empty;

_Image.Draw(region0, green, 2);

CvInvoke.Imwrite(@"C:\Temp\anh0.jpg", Images_[0]);

// VUNG 1 - KIEM TRA SO LUONG TU DIEN Rectangle region1 = new Rectangle(0, 55, 140, 86); _Image.ROI = region1;

Images_[1] = _Image.Copy();

Inspection.CountComponentContour(Images_[1], out Images_[1]); _Image.ROI = Rectangle.Empty;

_Image.Draw(region1, green, 2);

CvInvoke.Imwrite(@"C:\Temp\anh1.jpg", Images_[1]); // VUNG 2 - KIEM TRA SO LUONG NUT NHAN Rectangle region2 = new Rectangle(0, 129, 80, 160); _Image.ROI = region2;

Images_[2] = _Image.Copy();

Inspection.CountComponentContour(Images_[2], out Images_[2]); _Image.ROI = Rectangle.Empty;

_Image.Draw(region2, green, 2);

CvInvoke.Imwrite(@"C:\Temp\anh2.jpg", Images_[2]); // VUNG 3 - KIEM TRA SO LUONG LED

Rectangle region3 = new Rectangle(300, 170, 60, 270); _Image.ROI = region3;

Images_[3] = _Image.Copy(); _Image.ROI = Rectangle.Empty; _Image.Draw(region3, green, 2);

CvInvoke.Imwrite(@"C:\Temp\anh3.jpg", Images_[3]); // VUNG 4 - KIEM TRA SO LUONG Transitor

//Rectangle region4 = new Rectangle(530, 417, 350, 90); //_Image.ROI = region4;

//Images_[4] = _Image.Copy(); // _Image.ROI = Rectangle.Empty; //_Image.Draw(region4, green, 2); // VUNG 5 - KIEM TRA DIEN TRO

// Rectangle region5 = new Rectangle(460,280, 80, 180); // _Image.ROI = region5;

// Images_[5] = _Image.Copy(); //_Image.ROI = Rectangle.Empty; //_Image.Draw(region5, green, 2); //for (int i =0; i<7; i++)

//{

// var imgP = Path.Combine(imgPath, "region_" + i + ".jpg"); // CvInvoke.Imwrite(imgP, Images_[i]);

// return

Image_ = _Image.Clone(); }

// Arduino region

private void btnConnect_Click(object sender, EventArgs e) { if (!isConnected) { connectToArduino(); } else { DisconectArduino(); } }

private void connectToArduino() {

isConnected = true;

string selectPort = cmbPort.GetItemText(cmbPort.SelectedItem);

serialPort1 = new SerialPort(selectPort, 9600, Parity.None, 8, StopBits.One); serialPort1.RtsEnable = true; serialPort1.DtrEnable = true; serialPort1.Open(); //serialPort1.Write("#START\n"); btnConnect.Text = "Disconnect"; serialPort1.DataReceived += serialPort1_DataReceived; }

private void DisconectArduino() {

isConnected = false; serialPort1.Close();

btnConnect.Text = "Connect"; }

// Send_data

private void Send_Data(string content) { if (isConnected) { serialPort1.WriteLine(content); } }

private string Get_Data() { string message = ""; if (isConnected) { message = serialPort1.ReadExisting(); } return message; }

private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)

{

string messageIn = Get_Data();

if (!string.IsNullOrEmpty(messageIn)) {

updateValueCallBack _infor = new updateValueCallBack(updateValue); this.Invoke(_infor, new object[] { messageIn });

} }

public delegate void updateValueCallBack(string messageIn); public void updateValue(string messageIn)

{

string[] message = messageIn.Split('-'); Console.WriteLine(messageIn); int mode = 0; if (!string.IsNullOrEmpty(message[0])) mode = Int32.Parse(message[0]); if (mode == 1) {

tbxInfor.Text = "KẾT NỐI MÁY KIỂM THÀNH CÔNG" + Environment.NewLine; openCamera(); } else if (mode == 2) { m_bDetectPCB = true; cmbSample.Text = "Camera"; } }

private void getAvailablePort() {

Ports = SerialPort.GetPortNames(); }

} }

using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using Emgu.CV; using Emgu.CV.Features2D; using Emgu.CV.Structure; using Emgu.CV.Util; namespace Kiemtramach.Feature_Matching { public class FTMC { VectorOfPoint m_finalPoints; Mat m_homography; VectorOfKeyPoint m_templateKeyPoints; VectorOfKeyPoint m_sceneKeyPoints; Mat m_templateDescriptor; Mat m_sceneDescriptor; VectorOfVectorOfDMatch m_matches; Brisk m_featureDetector; public FTMC() { m_finalPoints = null; m_homography = null;

m_templateKeyPoints = new VectorOfKeyPoint(); m_sceneKeyPoints = new VectorOfKeyPoint(); m_templateDescriptor = new Mat();

m_sceneDescriptor = new Mat();

m_matches = new VectorOfVectorOfDMatch(); m_featureDetector = new Brisk();

}

public void ProcessImage(Image<Gray,byte> template, Image<Gray, byte> sceneImage, ref VectorOfPoint vp)

{ try { Mat mask; int k = 2; double uniqueThreshold = 0.8; m_featureDetector.DetectAndCompute(template, null,m_templateKeyPoints, m_templateDescriptor, false);

m_featureDetector.DetectAndCompute(sceneImage, null, m_sceneKeyPoints, m_sceneDescriptor, false);

// Matching

BFMatcher matcher = new BFMatcher(DistanceType.Hamming); matcher.Add(m_templateDescriptor);

matcher.KnnMatch(m_sceneDescriptor, m_matches, k);

mask = new Mat(m_matches.Size, 1, Emgu.CV.CvEnum.DepthType.Cv8U, 1); mask.SetTo(new MCvScalar(255)); Features2DToolbox.VoteForUniqueness(m_matches, uniqueThreshold, mask); int count = Features2DToolbox.VoteForSizeAndOrientation(m_templateKeyPoints, m_sceneKeyPoints, m_matches, mask,1.5,20);

if(count >=4) {

m_homography =

Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(m_templateKeyPoi nts, m_sceneKeyPoints, m_matches, mask, 5);

}

if(m_homography != null) {

Rectangle rect = new Rectangle(Point.Empty, template.Size); PointF[] pts = new PointF[]

{

new PointF(rect.Left, rect.Bottom), new PointF(rect.Right, rect.Bottom), new PointF(rect.Right, rect.Top), new PointF(rect.Left, rect.Top)

};

pts = CvInvoke.PerspectiveTransform(pts, m_homography);

Point[] points = Array.ConvertAll<PointF, Point>(pts, Point.Round); vp = new VectorOfPoint(points);

} }

catch( Exception ex) { } finally { // continue program; } } }

}

// Part 2.Process ROI using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using Emgu.CV; using Emgu.CV.Structure; using Emgu.CV.Util; using Emgu.CV.CvEnum; namespace Kiemtramach.ProcessROI {

public class Inspection {

// Count component based on FindContour - Region0, Region2, region3 public static int CountComponentContour(Image<Bgr, byte> _img, out Image<Bgr, byte> Img_)

{

int numComponent = 0; Mat ImgSource = _img.Mat; Mat ImgDest = new Mat();

Mat ResultImage = Mat.Zeros( ImgSource.Height, ImgSource.Width, DepthType.Cv8U,3);

ImgDest = ImgSource.Clone();

CvInvoke.CvtColor(ImgDest, ImgDest, Emgu.CV.CvEnum.ColorConversion.Bgr2Gray);

CvInvoke.Threshold(ImgDest, ImgDest, 0, 150, ThresholdType.Binary| ThresholdType.Triangle);

CvInvoke.Imwrite(@"C:\Temp\anhB.jpg", ImgDest);

Mat kernel = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(5,5), new Point(-1, -1));

CvInvoke.MorphologyEx(ImgDest, ImgDest,MorphOp.Close, kernel, new Point(-1, -1), 2, BorderType.Constant, new MCvScalar(0, 0, 255));

VectorOfVectorOfPoint contour = new VectorOfVectorOfPoint(); CvInvoke.FindContours(ImgDest, contour, null,

Emgu.CV.CvEnum.RetrType.External,

Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple);

for(int i = 0; i < contour.Size; i++) {

Rectangle rect = CvInvoke.BoundingRectangle(contour[i]); if ( rect.Width < 8 || rect.Height < 8) continue;

if (rect.Width > 80|| rect.Height > 80) continue;

_img.DrawPolyline(contour[i].ToArray(), false, new Bgr(0, 0, 255), 2); numComponent++;

}

Img_ = _img.Clone(); return numComponent; }

public static int CountComponentContour_HSV(Image<Bgr, byte> _img, Hsv _valueLow, Hsv _valueHeight, out Image<Bgr, byte> Img_)

int numComponent = 0; Mat temp = new Mat();

Image<Hsv, byte> hsvImg = _img.Convert<Hsv, byte>();

Image<Gray, byte> grayimg = hsvImg.InRange(_valueLow, _valueHeight);

Mat kernel = CvInvoke.GetStructuringElement(ElementShape.Ellipse, new Size(1, 1), new Point(-1, -1));

CvInvoke.MorphologyEx(grayimg, grayimg, MorphOp.Close, kernel, new Point(-1, -1), 2, BorderType.Isolated, new MCvScalar(0, 0, 255));

VectorOfVectorOfPoint contour = new VectorOfVectorOfPoint(); CvInvoke.FindContours(grayimg, contour, null,

Emgu.CV.CvEnum.RetrType.External,

Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple); for (int i = 0; i < contour.Size; i++)

{

Rectangle rect = CvInvoke.BoundingRectangle(contour[i]); if (rect.Width < 15 || rect.Height < 15) continue;

if (rect.Width > 60 || rect.Height > 60) continue;

_img.DrawPolyline(contour[i].ToArray(), false, new Bgr(0, 0, 255), 2); numComponent++; } Img_ = _img.Clone(); return numComponent; } } }

Một phần của tài liệu HỆ THỐNG KIỂM TRA LỖI TRÊN BOARD MẠCH ĐIỆN TỬ (Trang 50 - 70)

Tải bản đầy đủ (DOCX)

(70 trang)
w