1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
#pragma once
 
#include "ThreadControl.h"
#include "DefectStorage.h"
#include "GrabberControl.h"
#include "Glass_Data.h"
#include "GlassRecipe.h"
#include "HardwareSettings.h"
#include "SISBuffer.h"
#include "Global_Define.h"
 
#if USE_WEBSOCKET
#include "WebSocketClientPool.h"
#endif // USE_WEBSOCKET
 
interface IInspect2Sequence
{
    virtual void            II2S_InspectionEnd(int iCamID,int iScan) = 0;        
};
 
enum    ERR_FIND_GLASSSTARTLINE {ERR_FINDGLASSSTART_FAIL=0, ERR_FINDGLASSSTART_SUCCESS, ERR_FINDGLASSSTART_FIND_FAIL, ERR_FINDGLASSSTART_COUNT};
 
class CInspectCamera : public IThreadWorker
{
public:
    CInspectCamera(int iCam=0);
    virtual ~CInspectCamera(void);
 
public:
    virtual BOOL        OnThreadRun(int iThread, CInspectThread *pInspectThread);
    virtual BOOL        OnThreadEnd(int iThread, CInspectThread *pInspectThread);
    virtual BOOL        OnThreadEndAll();
 
public:
    void                ReleaseThread();
    int                    InitInspect(int nThread,int maxDefect=5000);
    int                    ReInitThread(int nThread);
    void                SetParameter(CGlassRecipe *pRecipe,CHardwareSettings *pHW);
    void                SetGlassData(CGlass_Data *pGlassData);
    void                SetGrabber(CGrabberControl *pGrabber);
    void                SetI2S(IInspect2Sequence *pI2S){m_pII2S=pI2S;}
    BOOL                ScanStart(int iScan);    
    void                SetProcessEnd(){m_bExitThread=TRUE;}
    int                    GetDefectCount();
    CDefect                *GetDefect(int iDefect);
 
    pINSPECTFULLIMAGE_BUFFER GetFullImgBuffer(int iScan){return &m_FullImgBuffer[iScan];}
    void                ReleaseFullBuffer();
    
    void                SetViewScanHWnd(HWND hWnd){m_hWndViewScan=hWnd;}
    void                SetSimulation(BOOL bSimulation);
 
protected:    
    BOOL                ScanStartThread();        
    DimensionDir        GetDimension(int iScan);
    BOOL                GetCheckFrame(stFrameIndex stFrame);
    void                SetGrabEnd(int iScan);    
 
    // 0. Start Line
    BOOL                CheckStartLineFrame(DimensionDir eDim,int iFrame);
    BOOL                FindGlassStartLine(DimensionDir emDim, stFrameIndex stFrame);
    BOOL                MakeNotchArea(DimensionDir emDim);    // ½ÃÀÛ¼±À» Ã£À¸¸é Notch ¿µ¿ªÀ» ¹Ì¸® ¸¸µé¾î ³õ´Â´Ù.
 
    // 1. Process Frame
    BOOL                ProcessFrame(int iThread,DimensionDir emDim, stFrameIndex stFrame);
 
    // 2. End Line
    BOOL                FindEndLine(int iThread,DimensionDir emDim, stFrameIndex stFrame);
 
    // 3. Side Line
    BOOL                FindSideLine(int iThread,DimensionDir emDim, stFrameIndex stFrame);
    BOOL                FindSideLine_ExceptNotch(int iThread,DimensionDir emDim, stFrameIndex stFrame);
 
    // 4. Find Top Corner
    BOOL                FindCorner(int iThread,DimensionDir emDim, stFrameIndex stFrame,int nPos,CRect rtConnerRoi);
    BOOL                FindTopCorner(int iThread,DimensionDir emDim, stFrameIndex stFrame);
    BOOL                FindTopCorner_None(int iThread,DimensionDir emDim, stFrameIndex stFrame);
    BOOL                FindTopCorner_CCut(int iThread,DimensionDir emDim, stFrameIndex stFrame);
    BOOL                FindTopCorner_RCut(int iThread,DimensionDir emDim, stFrameIndex stFrame);
 
    // 5. Find Top Align Mark 
    BOOL                FindTopAlignMark(int iThread,DimensionDir eDim, stFrameIndex stFrame);
    BOOL                FindTopAlignMark_Virtual(int iThread,DimensionDir eDim, stFrameIndex stFrame);
    BOOL                FindTopAlignMark_TempleteMatching(int iThread,DimensionDir eDim, stFrameIndex stFrame);
 
    // 6. Find Bot Corner
    BOOL                FindBotCorner(int iThread,DimensionDir eDim, stFrameIndex stFrame);
    BOOL                FindBotCorner_None(int iThread,DimensionDir emDim, stFrameIndex stFrame);
    BOOL                FindBotCorner_CCut(int iThread,DimensionDir emDim, stFrameIndex stFrame);
    BOOL                FindBotCorner_RCut(int iThread,DimensionDir emDim, stFrameIndex stFrame);
 
    // 7. Find Bot Align Mark
    BOOL                FindBotAlignMark(int iThread,DimensionDir eDim, stFrameIndex stFrame);
    BOOL                FindBotAlignMark_Virtual(int iThread,DimensionDir eDim, stFrameIndex stFrame);
    BOOL                FindBotAlignMark_TempleteMatching(int iThread,DimensionDir eDim, stFrameIndex stFrame);
 
    // 8. Inspect Defect
    BOOL                InspectDefect(int iThread,DimensionDir eDim, stFrameIndex stFrame);
    BOOL                InspectDefect_Side(int iThread,DimensionDir eDim, stFrameIndex stFrame);    // Notch..
    BOOL                MakeInspectRegion(int iThread,DimensionDir eDim,int iScan,int iFrame, CRect& rtInspectArea, int& nCutLine);
    BOOL                MakeInspectRegion(int iThread,DimensionDir eDim,int iScan,int iFrame, std::vector<CRect> & vecInspectArea, int& nCutLine);
    BOOL                InspectDefect_Process(int iThread,DimensionDir eDim,int iScan,int iFrame, CRect rtInspectArea, int nCutLine, eSideInsType emInsType, std::vector<CDefect_Info>* pDefectList);
 
    BOOL                Binarization_Threshold_Suppress(COwnerBuffer* pImageData, COwnerBuffer* pBinImage, int nThresholdLow, int nThresholdHigh);
    BOOL                Binarization_Threshold_Pitch_X(COwnerBuffer* pImageData, COwnerBuffer* pBinImage, int nPitch, int nThreshold);
    BOOL                Binarization_Threshold_Pitch_Y(COwnerBuffer* pImageData, COwnerBuffer* pBinImage, int nPitch, int nThreshold);
    BOOL                Binarization_Threshold_Pitch_X_Suppress(COwnerBuffer* pImageData, COwnerBuffer* pBinImage, int nPitch, int nThresholdPitch, int nThresholdLow, int nThresholdHigh);
    BOOL                Binarization_Threshold_Pitch_Y_Suppress(COwnerBuffer* pImageData, COwnerBuffer* pBinImage, int nPitch, int nThresholdPitch, int nThresholdLow, int nThresholdHigh);
    BOOL                DefectProcess(DimensionDir eDim,int iScan,int iFrame, COwnerBuffer* pImageData, COwnerBuffer* pBinImage, CRect rtROIPos, int nMinSize, int nMinSizeX, int nMinSizeY, int nDilation, BOOL bStartNearFilter, int nStartNearFilterRange, DefectLocation defectType, std::vector<CDefect_Info>* pDefectList);
    BOOL                DefectProcess(DimensionDir eDim,int iScan,int iFrame, IplImage* pImageData, IplImage* pBinImage, CRect rtROIPos, int nMinSize, int nMinSizeX, int nMinSizeY, int nDilation, BOOL bStartNearFilter, int nStartNearFilterRange, DefectLocation defectType, std::vector<CDefect_Info>* pDefectList);
 
    // 9. Notch Inspect
    BOOL                Notch_Process(int iThread,DimensionDir emDim, stFrameIndex stFrame);
    void                Notch_Process_PreProcess(DimensionDir emDim, stFrameIndex stFrame, int nNotchIdx, IplImage* scr, IplImage* img_Edge, IplImage* img_Bin, CRect rtROI);
    void                Notch_Process_PreProcess_2(DimensionDir emDim, stFrameIndex stFrame, int nNotchIdx, IplImage* scr, IplImage* img_Edge, IplImage* img_Bin, CRect rtROI);
    void                Notch_Process_Measure(DimensionDir emDim, stFrameIndex stFrame, int nNotchIdx, IplImage* scr,IplImage* img_Edge,IplImage* img_Bin, CRect rtROI);
    bool                Notch_Process_Calculate(DimensionDir emDim, stFrameIndex stFrame, int nNotchIdx, IplImage* scr,IplImage* img_Edge,IplImage* img_Bin, CRect rtROI);
    void                Notch_Process_Judge(DimensionDir emDim, stFrameIndex stFrame, int nNotchIdx, IplImage* scr,IplImage* img_Edge,IplImage* img_Bin, CRect rtROI);
    void                Notch_Process_Defect(DimensionDir emDim, stFrameIndex stFrame, int nNotchIdx, IplImage* scr,IplImage* img_Edge,IplImage* img_Bin, CRect rtROI);
    void                Notch_Process_FindCircle(DimensionDir emDim, stFrameIndex stFrame, int nNotchIdx);
 
    // 10. Find Measure
    BOOL                Measure(int iThread,DimensionDir emDim, stFrameIndex stFrame);
    BOOL                Measure_Side(int iThread,DimensionDir emDim, stFrameIndex stFrame);
    BOOL                Measure_TopCorner(int iThread,DimensionDir emDim, stFrameIndex stFrame);
    BOOL                Measure_TopCorner_CCut(int iThread,DimensionDir emDim, stFrameIndex stFrame);
    BOOL                Measure_TopCorner_RCut(int iThread,DimensionDir emDim, stFrameIndex stFrame);
 
    BOOL                Measure_BotCorner(int iThread,DimensionDir emDim, stFrameIndex stFrame);
    BOOL                Measure_BotCorner_CCut(int iThread,DimensionDir emDim, stFrameIndex stFrame);
    BOOL                Measure_BotCorner_RCut(int iThread,DimensionDir emDim, stFrameIndex stFrame);
 
    // 11. User Defect Area Process
    BOOL                UserDefect_Process(int iThread,DimensionDir emDim, stFrameIndex stFrame);
    BOOL                InspectDefect_UserDefectProcess(int iThread,DimensionDir emDim, stFrameIndex stFrame, int nUserDefectIdx, CRect rtUserDefectArea, std::vector<CDefect_Info>* pDefectList);
 
    // 12. Exception Area Process
    BOOL                ExceptionArea_Process(int iThread,DimensionDir emDim, stFrameIndex stFrame);
 
    //13. ÊÓ¾õ¹¦ÄÜ
    void FinallyVisionProc(DimensionDir eDim);
 
protected:    
    void                SaveFullImageCopy(int iScan);
    int                    GetLeftMargin(int iCam,int iScan);
    void                GetFrameSize(int iCam,int iScan,int &nFrameWidth,int &nFrameHeight);    
    void                SaveGlassLineImage(int iScan,int nEndLine,int nXPos,DimensionDir emDim,CString strName);
    BOOL                GetCheckExit(){return m_bExitThread;}
 
    void                ScanRegionSet(stFrameIndex stFrame);
 
    BOOL                CheckProcessEnd(int iThread,stFrameIndex stFrame);        
    BOOL                CheckThreadEnd(int iThread,stFrameIndex stFrame);
    ERR_FIND_GLASSSTARTLINE        IsGlassStartLine(int iThread,int &iScan);
 
 
    int                    GetThreadEndCount(int iScan);
 
    void                ResetFrameFinish(int nCurrentScanIdx);
    void                SetFrameFinishEndFrame(int nCurrentScanIdx, int nFrameIdx);
    void                SetFrameFinish(int nCurrentScanIdx, int nCurrentFrameIdx);
    BOOL                CheckAllFrameFinish(int nCurrentScanIdx);
 
    double                GetPixelToUm_X(double dPixel_X);
    double                GetPixelToUm_Y(double dPixel_Y);
    double                GetUmToPixel_X(double dUm_X);
    double                GetUmToPixel_Y(double dUm_Y);
    double                GetUm_Distance(CPoint ptStart_pxl, CPoint ptEnd_pxl);
    CRect                GetValidRect(CRect rtInput);
 
    // Rotate
    BOOL                GetAlignRotate(DimensionDir emDim, CPoint ptSetTopMark, CPoint ptSetBotMark, CRect rtSetArea, CRect& bRotateArea);
 
    BOOL                CopyRectImg(LPBYTE pOrg,LPBYTE pTgt,CSize szImg,CRect &rectIns);
    void                SaveDebugImage(DimensionDir eDim, stFrameIndex stFrame, COwnerBuffer* pBuffer, CString strFileName);
    void                SaveDebugImage(DimensionDir eDim, stFrameIndex stFrame, IplImage* pBuffer, CString strFileName);
    void                SaveDebugImage(DimensionDir eDim, stFrameIndex stFrame, cv::Mat image, CString strFileName);
    CString                GetSideName(DimensionDir eDim);
 
#if USE_WEBSOCKET
public:
    void                SetWebSocketClients(WebSocketClientPool* wsClients);
 
protected:
    std::string            CreateJsonWSSendData(const WSSendData& data);
    double                GetCurrentTimestamp();
 
    void                HandleAlarmNotification();
    void                SendImageDataOverWebSocket(DimensionDir emDim, stFrameIndex stFrame, int index, BYTE* data, int state, int left, int top, int width, int height);
    BOOL                SliceAndSendImageViaWebSocket(int iThread, DimensionDir eDim, stFrameIndex stFrame);
    BOOL                SendFrameScanDataOverWebSocket(int iThread, DimensionDir eDim, stFrameIndex stFrame);
 
protected:
    WebSocketClientPool *m_wsClients;
#endif // USE_WEBSOCKET
 
#if USE_AI_DETECT
protected:
    AiDetectEx* m_pAiDetectEx;
    bool m_bUseAIDetect;
    std::string m_strChannel;
 
public:
    void SetUseAIDetect(bool bUseAIDetect);
    long long GetCurrentTimestamp();
 
protected:
    BOOL SendFrameScanDataOverAI(int iThread, DimensionDir eDim, stFrameIndex stFrame);
#endif // USE_AI_DETECT
 
protected:
    CThreadControl        *m_pThreadControl;
    CGlassRecipe        *m_pRecipe;
    CHardwareSettings    *m_pHardparm;
    CGrabberControl        *m_pGrabber;
    CGlass_Data            *m_pGlassData;
    IInspect2Sequence    *m_pII2S;
    CDefectControl        *m_pDefectControl;
 
#if HALCON_VISION_KEY
    double m_fInspectLastTime[8];
#endif // HALCON_VISION_KEY
 
protected:
    int                    m_iCamera;
    int                    m_iScan;    
    int                    m_iSideLine[MAX_SCAN_COUNT];
    BOOL                m_bExitThread;
 
    // Resolution
    int                    m_nFrameWidth;
    int                    m_nFrameHeight;
    double                m_dPixelSizeX;
    double                m_dPixelSizeY;
 
    int                    m_iThreadEnd[MAX_SCAN_COUNT][MAX_THREAD];    
    CCriticalSection    m_csThreadEnd;
    CCriticalSection    m_csThreadGlassStart;
 
    CCriticalSection    m_csTopCorner;
    CCriticalSection    m_csThreadTopAlignMark;
    CCriticalSection    m_csBotCorner;
    CCriticalSection    m_csThreadBotAlignMark;
 
    CCriticalSection    m_csSaveimage;
    BOOL                m_bFindGlassStart[MAX_SCAN_COUNT];
 
    INSPECTFULLIMAGE_BUFFER    m_FullImgBuffer[MAX_SCAN_COUNT];
 
    HWND                m_hWndViewScan;
    PROG_MSG            m_MsgJob;
 
    CCriticalSection    m_csFrameFinishCheck;
    int                    m_nFrameFinishIdx[MAX_SCAN_COUNT];
    BOOL                m_bFrameFinish[MAX_SCAN_COUNT][MAX_FRAM_COUNT];
 
    BOOL                m_bSimulation;
 
    int                    m_nChamferOffset_um;
};