박민혀기

CELLON I 시료 걸쇠 Sobel 추출 UI 적용 데모(20230323) 본문

CELLON Vision/Source Code

CELLON I 시료 걸쇠 Sobel 추출 UI 적용 데모(20230323)

박민혀기 2023. 3. 23. 17:10

CELLON I 시료 걸쇠 Sobel 추출 UI 적용 데모(20230323)

일치도 X

UI Version : 1.2

Camera Resolution : 640x480

 

2023.03.20에 업로드한 "CELLON I 시료 걸쇠 Sobel 추출"을 기반으로 개발

추출된 ROI 영역을 바이너리 이미지로 변환후 0의 양과 255의 양을 비교하여 판별

#include <iostream>
#include <math.h>
#include "opencv2/opencv.hpp"

using namespace std;
using namespace cv;

unsigned int	Number_of_ROI = 1;
unsigned int	Accuracy_Percent[5];
unsigned int	Number_of_ROI_Temp;
unsigned int	Accuracy_Percent_Temp[5];
int				flag = 0;
bool			Setting_Mode_Flag = false;
bool			Config_Flag = false;
unsigned int	Compare_Total, Compare_Good, Compare_Bad;

Mat				frame, Show_Frame, Inspect_ROI;
vector<Mat>		Standard_ROI;
Point			temp, temp2, temp_ROI_Write;
vector<Point>	Inspect_ROI_Point;
vector<Point>	State_Message_Point;
vector<String>	State_Message_S;
Point			Rectangle_Point_x = Point(90, 90);
Point			Rectangle_Point_y = Point(165, 90);
Size			Rectangle_Size = Size(20, 15);
Point			Reset_Button_Point = Point(135, 230);
Size			Reset_Button_Size = Point(50, 20);
int				button_dis = 30;
double			Message_Font_Size = 0.4;
Point			Resolution_Point = Point(90, 200);
unsigned int	width, height;

///////////////////////Count Segment/////////////////////////
void State_Message() {
	if (State_Message_S[6] != State_Message_S[7]) {
		State_Message_S[0] = State_Message_S[1];
		State_Message_S[1] = State_Message_S[2];
		State_Message_S[2] = State_Message_S[3];
		State_Message_S[3] = State_Message_S[4];
		State_Message_S[4] = State_Message_S[5];
		State_Message_S[5] = State_Message_S[6];
		State_Message_S[6] = State_Message_S[7];
	}

	for (int i = 6; i >= 0; i--) {
		putText(Show_Frame, State_Message_S[i], State_Message_Point[i], FONT_HERSHEY_DUPLEX, Message_Font_Size, Scalar(0, 0, 0), 2);
		putText(Show_Frame, State_Message_S[i], State_Message_Point[i], FONT_HERSHEY_DUPLEX, Message_Font_Size, Scalar(125, 125, 125), 1);
	}
}

void Compare_State(Scalar state_scalar) {
	rectangle(Show_Frame, Rect(width - 135, height - 30, 95, 25), Scalar(0, 0, 0), -1);
	rectangle(Show_Frame, Rect(width - 130, height - 25, 85, 15), state_scalar, -1);
}

void Compare_Result() {
	char Compare_Total_S[15], Compare_Good_S[15], Compare_Bad_S[15];

	sprintf_s(Compare_Total_S, "TOTAL  : %d", Compare_Total);
	sprintf_s(Compare_Good_S, "GOOD  : %d", Compare_Good);
	sprintf_s(Compare_Bad_S, "BAD    : %d", Compare_Bad);

	putText(Show_Frame, Compare_Total_S, Point(width - 135, height - 70), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 0), 3);
	putText(Show_Frame, Compare_Total_S, Point(width - 135, height - 70), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 255, 0), 1);

	putText(Show_Frame, Compare_Good_S, Point(width - 135, height - 55), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 0), 3);
	putText(Show_Frame, Compare_Good_S, Point(width - 135, height - 55), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 255, 0), 1);

	putText(Show_Frame, Compare_Bad_S, Point(width - 135, height - 40), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 0), 3);
	putText(Show_Frame, Compare_Bad_S, Point(width - 135, height - 40), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 255, 0), 1);

}

void ALAM_Marking() {
	putText(Show_Frame, "=", Point(14, 42), FONT_HERSHEY_DUPLEX, 1, Scalar(0, 0, 0), 5);
	putText(Show_Frame, "CELLON", Point(45, 40), FONT_HERSHEY_DUPLEX, 0.6, Scalar(0, 0, 0), 4);
	putText(Show_Frame, "=", Point(14, 42), FONT_HERSHEY_DUPLEX, 1, Scalar(0, 255, 255), 2);
	putText(Show_Frame, "CELLON", Point(45, 40), FONT_HERSHEY_DUPLEX, 0.6, Scalar(0, 255, 255), 1);
}

void Center_Marking(double width, double height) {
	line(Show_Frame, Point(width / 2, height / 2 + 15), Point(width / 2, height / 2 - 15), Scalar(0, 0, 255), 1);
	line(Show_Frame, Point(width / 2 + 15, height / 2), Point(width / 2 - 15, height / 2), Scalar(0, 0, 255), 1);
}

//수정
void Setting_Mode() {
	char	Accuracy_Percent_S[5];
	char	Number_of_ROI_S[5];
	Point	Title_Point = Point(5, 102);
	Point	Value_Point = Point(128, 102);

	//Title Box
	rectangle(Show_Frame, Rect(Title_Point - Point(2, 30) - Point(3, 3), Title_Point + Point(195, 200) + Point(3, 3)), Scalar(0, 0, 0), -1);
	rectangle(Show_Frame, Rect(Title_Point - Point(2, 30), Title_Point + Point(195, 200)), Scalar(125, 125, 125), -1);

	putText(Show_Frame, "ROI_Num", Title_Point, FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 0), 3);
	putText(Show_Frame, "ROI_Num", Title_Point, FONT_HERSHEY_DUPLEX, 0.5, Scalar(255, 255, 255), 1);
	putText(Show_Frame, "ACC_1", Title_Point + Point(0, button_dis), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 0), 3);
	putText(Show_Frame, "ACC_1", Title_Point + Point(0, button_dis), FONT_HERSHEY_DUPLEX, 0.5, Scalar(255, 255, 255), 1);
	putText(Show_Frame, "ACC_2", Title_Point + Point(0, button_dis) * 2, FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 0), 3);
	putText(Show_Frame, "ACC_2", Title_Point + Point(0, button_dis) * 2, FONT_HERSHEY_DUPLEX, 0.5, Scalar(255, 255, 255), 1);
	putText(Show_Frame, "ACC_3", Title_Point + Point(0, button_dis) * 3, FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 0), 3);
	putText(Show_Frame, "ACC_3", Title_Point + Point(0, button_dis) * 3, FONT_HERSHEY_DUPLEX, 0.5, Scalar(255, 255, 255), 1);
	putText(Show_Frame, "ACC_4", Title_Point + Point(0, button_dis) * 4, FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 0), 3);
	putText(Show_Frame, "ACC_4", Title_Point + Point(0, button_dis) * 4, FONT_HERSHEY_DUPLEX, 0.5, Scalar(255, 255, 255), 1);
	putText(Show_Frame, "ACC_5", Title_Point + Point(0, button_dis) * 5, FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 0), 3);
	putText(Show_Frame, "ACC_5", Title_Point + Point(0, button_dis) * 5, FONT_HERSHEY_DUPLEX, 0.5, Scalar(255, 255, 255), 1);

	/*////////////////////		+, - Button		////////////////////*/
	//	-	//
	rectangle(Show_Frame, Rect(Rectangle_Point_x + Point(-3, -3), Rectangle_Size + Size(6, 6)), Scalar(0, 0, 0), -1);
	rectangle(Show_Frame, Rect(Rectangle_Point_x, Rectangle_Size), Scalar(170, 170, 170), -1);
	rectangle(Show_Frame, Rect(Rectangle_Point_x + Point(0, button_dis) + Point(-3, -3), Rectangle_Size + Size(6, 6)), Scalar(0, 0, 0), -1);
	rectangle(Show_Frame, Rect(Rectangle_Point_x + Point(0, button_dis), Rectangle_Size), Scalar(170, 170, 170), -1);
	rectangle(Show_Frame, Rect(Rectangle_Point_x + Point(0, button_dis) * 2 + Point(-3, -3), Rectangle_Size + Size(6, 6)), Scalar(0, 0, 0), -1);
	rectangle(Show_Frame, Rect(Rectangle_Point_x + Point(0, button_dis) * 2, Rectangle_Size), Scalar(170, 170, 170), -1);
	rectangle(Show_Frame, Rect(Rectangle_Point_x + Point(0, button_dis) * 3 + Point(-3, -3), Rectangle_Size + Size(6, 6)), Scalar(0, 0, 0), -1);
	rectangle(Show_Frame, Rect(Rectangle_Point_x + Point(0, button_dis) * 3, Rectangle_Size), Scalar(170, 170, 170), -1);
	rectangle(Show_Frame, Rect(Rectangle_Point_x + Point(0, button_dis) * 4 + Point(-3, -3), Rectangle_Size + Size(6, 6)), Scalar(0, 0, 0), -1);
	rectangle(Show_Frame, Rect(Rectangle_Point_x + Point(0, button_dis) * 4, Rectangle_Size), Scalar(170, 170, 170), -1);
	rectangle(Show_Frame, Rect(Rectangle_Point_x + Point(0, button_dis) * 5 + Point(-3, -3), Rectangle_Size + Size(6, 6)), Scalar(0, 0, 0), -1);
	rectangle(Show_Frame, Rect(Rectangle_Point_x + Point(0, button_dis) * 5, Rectangle_Size), Scalar(170, 170, 170), -1);

	//	+	//
	rectangle(Show_Frame, Rect(Rectangle_Point_y + Point(-3, -3), Rectangle_Size + Size(6, 6)), Scalar(0, 0, 0), -1);
	rectangle(Show_Frame, Rect(Rectangle_Point_y, Rectangle_Size), Scalar(170, 170, 170), -1);
	rectangle(Show_Frame, Rect(Rectangle_Point_y + Point(0, button_dis) + Point(-3, -3), Rectangle_Size + Size(6, 6)), Scalar(0, 0, 0), -1);
	rectangle(Show_Frame, Rect(Rectangle_Point_y + Point(0, button_dis), Rectangle_Size), Scalar(170, 170, 170), -1);
	rectangle(Show_Frame, Rect(Rectangle_Point_y + Point(0, button_dis) * 2 + Point(-3, -3), Rectangle_Size + Size(6, 6)), Scalar(0, 0, 0), -1);
	rectangle(Show_Frame, Rect(Rectangle_Point_y + Point(0, button_dis) * 2, Rectangle_Size), Scalar(170, 170, 170), -1);
	rectangle(Show_Frame, Rect(Rectangle_Point_y + Point(0, button_dis) * 3 + Point(-3, -3), Rectangle_Size + Size(6, 6)), Scalar(0, 0, 0), -1);
	rectangle(Show_Frame, Rect(Rectangle_Point_y + Point(0, button_dis) * 3, Rectangle_Size), Scalar(170, 170, 170), -1);
	rectangle(Show_Frame, Rect(Rectangle_Point_y + Point(0, button_dis) * 4 + Point(-3, -3), Rectangle_Size + Size(6, 6)), Scalar(0, 0, 0), -1);
	rectangle(Show_Frame, Rect(Rectangle_Point_y + Point(0, button_dis) * 4, Rectangle_Size), Scalar(170, 170, 170), -1);
	rectangle(Show_Frame, Rect(Rectangle_Point_y + Point(0, button_dis) * 5 + Point(-3, -3), Rectangle_Size + Size(6, 6)), Scalar(0, 0, 0), -1);
	rectangle(Show_Frame, Rect(Rectangle_Point_y + Point(0, button_dis) * 5, Rectangle_Size), Scalar(170, 170, 170), -1);

	/*////////////////////		+, - Button Text		////////////////////*/
	putText(Show_Frame, "-", Rectangle_Point_x + Point(3, 12), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 0), 1);
	putText(Show_Frame, "-", Rectangle_Point_x + Point(0, button_dis) + Point(3, 12), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 0), 1);
	putText(Show_Frame, "-", Rectangle_Point_x + Point(0, button_dis) * 2 + Point(3, 12), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 0), 1);
	putText(Show_Frame, "-", Rectangle_Point_x + Point(0, button_dis) * 3 + Point(3, 12), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 0), 1);
	putText(Show_Frame, "-", Rectangle_Point_x + Point(0, button_dis) * 4 + Point(3, 12), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 0), 1);
	putText(Show_Frame, "-", Rectangle_Point_x + Point(0, button_dis) * 5 + Point(3, 12), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 0), 1);

	putText(Show_Frame, "+", Rectangle_Point_y + Point(3, 12), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 0), 1);
	putText(Show_Frame, "+", Rectangle_Point_y + Point(0, button_dis) + Point(3, 12), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 0), 1);
	putText(Show_Frame, "+", Rectangle_Point_y + Point(0, button_dis) * 2 + Point(3, 12), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 0), 1);
	putText(Show_Frame, "+", Rectangle_Point_y + Point(0, button_dis) * 3 + Point(3, 12), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 0), 1);
	putText(Show_Frame, "+", Rectangle_Point_y + Point(0, button_dis) * 4 + Point(3, 12), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 0), 1);
	putText(Show_Frame, "+", Rectangle_Point_y + Point(0, button_dis) * 5 + Point(3, 12), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 0), 1);

	//OK Button
	rectangle(Show_Frame, Rect(Resolution_Point - Point(-45, -10 - button_dis - button_dis) + Point(-3, -3),
		Reset_Button_Size + Size(6, 6)), Scalar(0, 0, 0), -1);
	rectangle(Show_Frame, Rect(Resolution_Point - Point(-45, -10 - button_dis - button_dis), Reset_Button_Size), Scalar(170, 170, 170), -1);
	putText(Show_Frame, "OK", Resolution_Point - Point(-55, -25 - button_dis - button_dis), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 0), 1);

	//Cancel Button
	rectangle(Show_Frame, Rect(Resolution_Point - Point(15, -10 - button_dis - button_dis) + Point(-3, -3),
		Reset_Button_Size + Size(6, 6)), Scalar(0, 0, 0), -1);
	rectangle(Show_Frame, Rect(Resolution_Point - Point(15, -10 - button_dis - button_dis), Reset_Button_Size), Scalar(170, 170, 170), -1);
	putText(Show_Frame, "Cancel", Resolution_Point - Point(17, -25 - button_dis - button_dis), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 0), 1);

	sprintf_s(Number_of_ROI_S, "%d", Number_of_ROI);
	putText(Show_Frame, Number_of_ROI_S, Value_Point, FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 0), 3);
	putText(Show_Frame, Number_of_ROI_S, Value_Point, FONT_HERSHEY_DUPLEX, 0.5, Scalar(255, 255, 255), 1);

	sprintf_s(Accuracy_Percent_S, "%d", Accuracy_Percent[0]);
	putText(Show_Frame, Accuracy_Percent_S, Value_Point + Point(0, button_dis), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 0), 3);
	putText(Show_Frame, Accuracy_Percent_S, Value_Point + Point(0, button_dis), FONT_HERSHEY_DUPLEX, 0.5, Scalar(255, 255, 255), 1);
	if (Accuracy_Percent[1] == 0)	sprintf_s(Accuracy_Percent_S, "X");
	else	sprintf_s(Accuracy_Percent_S, "%d", Accuracy_Percent[1]);
	putText(Show_Frame, Accuracy_Percent_S, Value_Point + Point(0, button_dis) * 2, FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 0), 3);
	putText(Show_Frame, Accuracy_Percent_S, Value_Point + Point(0, button_dis) * 2, FONT_HERSHEY_DUPLEX, 0.5, Scalar(255, 255, 255), 1);
	if (Accuracy_Percent[2] == 0)	sprintf_s(Accuracy_Percent_S, "X");
	else	sprintf_s(Accuracy_Percent_S, "%d", Accuracy_Percent[2]);
	putText(Show_Frame, Accuracy_Percent_S, Value_Point + Point(0, button_dis) * 3, FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 0), 3);
	putText(Show_Frame, Accuracy_Percent_S, Value_Point + Point(0, button_dis) * 3, FONT_HERSHEY_DUPLEX, 0.5, Scalar(255, 255, 255), 1);
	if (Accuracy_Percent[3] == 0)	sprintf_s(Accuracy_Percent_S, "X");
	else	sprintf_s(Accuracy_Percent_S, "%d", Accuracy_Percent[3]);
	putText(Show_Frame, Accuracy_Percent_S, Value_Point + Point(0, button_dis) * 4, FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 0), 3);
	putText(Show_Frame, Accuracy_Percent_S, Value_Point + Point(0, button_dis) * 4, FONT_HERSHEY_DUPLEX, 0.5, Scalar(255, 255, 255), 1);
	if (Accuracy_Percent[4] == 0)	sprintf_s(Accuracy_Percent_S, "X");
	else	sprintf_s(Accuracy_Percent_S, "%d", Accuracy_Percent[4]);
	putText(Show_Frame, Accuracy_Percent_S, Value_Point + Point(0, button_dis) * 5, FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 0), 3);
	putText(Show_Frame, Accuracy_Percent_S, Value_Point + Point(0, button_dis) * 5, FONT_HERSHEY_DUPLEX, 0.5, Scalar(255, 255, 255), 1);
}

//수정
void Mouse_Event(int event, int x, int y, int flags, void* userdata) {
	if (Setting_Mode_Flag == true && event == EVENT_LBUTTONDOWN) {
		if (((Rectangle_Point_x.x <= x) && (Rectangle_Point_x.x + Rectangle_Size.width >= x)) &&
			((Rectangle_Point_x.y <= y) && (Rectangle_Point_x.y + Rectangle_Size.height >= y))) {		//1-1
			Number_of_ROI--;
			if (Number_of_ROI == 0) {
				Number_of_ROI = 1;
			}

			if (Number_of_ROI == 4) {
				Accuracy_Percent[4] = 0;
			}
			else if (Number_of_ROI == 3) {
				Accuracy_Percent[3] = 0;
				Accuracy_Percent[4] = 0;
			}
			else if (Number_of_ROI == 2) {
				Accuracy_Percent[2] = 0;
				Accuracy_Percent[3] = 0;
				Accuracy_Percent[4] = 0;
			}
			else if (Number_of_ROI == 1) {
				Accuracy_Percent[1] = 0;
				Accuracy_Percent[2] = 0;
				Accuracy_Percent[3] = 0;
				Accuracy_Percent[4] = 0;
			}
		}
		if (((Rectangle_Point_y.x <= x) && (Rectangle_Point_y.x + Rectangle_Size.width >= x)) &&
			((Rectangle_Point_y.y <= y) && (Rectangle_Point_y.y + Rectangle_Size.height >= y))) {		//1-2
			Number_of_ROI++;
			if (Number_of_ROI == 6) {
				Number_of_ROI = 5;
			}

			Accuracy_Percent[Number_of_ROI - 1] = 90;
		}

		if ((Rectangle_Point_x.x <= x) && (Rectangle_Point_x.x + Rectangle_Size.width >= x) &&
			((Rectangle_Point_x.y + button_dis <= y) && (Rectangle_Point_x.y + button_dis + Rectangle_Size.height >= y))) {		//2-1
			if (Accuracy_Percent[0] >= 90) {
				Accuracy_Percent[0]--;
			}
			else {
				Accuracy_Percent[0] -= 2;
			}

			if (Accuracy_Percent[0] == -1 || Accuracy_Percent[0] == -2) {
				Accuracy_Percent[0] = 0;
			}
		}
		if (((Rectangle_Point_y.x <= x) && (Rectangle_Point_y.x + Rectangle_Size.width >= x)) &&
			((Rectangle_Point_y.y + button_dis <= y) && (Rectangle_Point_y.y + button_dis + Rectangle_Size.height >= y))) {		//2-2
			if (Accuracy_Percent[0] >= 90) {
				Accuracy_Percent[0]++;
			}
			else {
				Accuracy_Percent[0] += 2;
			}

			if (Accuracy_Percent[0] == 101) {
				Accuracy_Percent[0] = 100;
			}
		}

		if ((Rectangle_Point_x.x <= x) && (Rectangle_Point_x.x + Rectangle_Size.width >= x) &&
			((Rectangle_Point_x.y + button_dis * 2 <= y) && (Rectangle_Point_x.y + button_dis * 2 + Rectangle_Size.height >= y)) &&
			Number_of_ROI > 1) {		//3-1
			if (Accuracy_Percent[1] >= 90) {
				Accuracy_Percent[1]--;
			}
			else {
				Accuracy_Percent[1] -= 2;
			}

			if (Accuracy_Percent[1] == -1 || Accuracy_Percent[1] == -2) {
				Accuracy_Percent[1] = 0;
			}
		}
		if (((Rectangle_Point_y.x <= x) && (Rectangle_Point_y.x + Rectangle_Size.width >= x)) &&
			((Rectangle_Point_y.y + button_dis * 2 <= y) && (Rectangle_Point_y.y + button_dis * 2 + Rectangle_Size.height >= y)) &&
			Number_of_ROI > 1) {		//3-2
			if (Accuracy_Percent[1] >= 90) {
				Accuracy_Percent[1]++;
			}
			else {
				Accuracy_Percent[1] += 2;
			}

			if (Accuracy_Percent[1] == 101) {
				Accuracy_Percent[1] = 100;
			}
		}

		if ((Rectangle_Point_x.x <= x) && (Rectangle_Point_x.x + Rectangle_Size.width >= x) &&
			((Rectangle_Point_x.y + button_dis * 3 <= y) && (Rectangle_Point_x.y + button_dis * 3 + Rectangle_Size.height >= y)) &&
			Number_of_ROI > 2) {		//4-1
			if (Accuracy_Percent[2] >= 90) {
				Accuracy_Percent[2]--;
			}
			else {
				Accuracy_Percent[2] -= 2;
			}

			if (Accuracy_Percent[2] == -1 || Accuracy_Percent[2] == -2) {
				Accuracy_Percent[2] = 0;
			}
		}
		if (((Rectangle_Point_y.x <= x) && (Rectangle_Point_y.x + Rectangle_Size.width >= x)) &&
			((Rectangle_Point_y.y + button_dis * 3 <= y) && (Rectangle_Point_y.y + button_dis * 3 + Rectangle_Size.height >= y)) &&
			Number_of_ROI > 2) {		//4-2
			if (Accuracy_Percent[2] >= 90) {
				Accuracy_Percent[2]++;
			}
			else {
				Accuracy_Percent[2] += 2;
			}

			if (Accuracy_Percent[2] == 101) {
				Accuracy_Percent[2] = 100;
			}
		}

		if ((Rectangle_Point_x.x <= x) && (Rectangle_Point_x.x + Rectangle_Size.width >= x) &&
			((Rectangle_Point_x.y + button_dis * 4 <= y) && (Rectangle_Point_x.y + button_dis * 4 + Rectangle_Size.height >= y)) &&
			Number_of_ROI > 3) {		//5-1
			if (Accuracy_Percent[3] >= 90) {
				Accuracy_Percent[3]--;
			}
			else {
				Accuracy_Percent[3] -= 2;
			}

			if (Accuracy_Percent[3] == -1 || Accuracy_Percent[3] == -2) {
				Accuracy_Percent[3] = 0;
			}
		}
		if (((Rectangle_Point_y.x <= x) && (Rectangle_Point_y.x + Rectangle_Size.width >= x)) &&
			((Rectangle_Point_y.y + button_dis * 4 <= y) && (Rectangle_Point_y.y + button_dis * 4 + Rectangle_Size.height >= y)) &&
			Number_of_ROI > 3) {		//5-2
			if (Accuracy_Percent[3] >= 90) {
				Accuracy_Percent[3]++;
			}
			else {
				Accuracy_Percent[3] += 2;
			}

			if (Accuracy_Percent[3] == 101) {
				Accuracy_Percent[3] = 100;
			}
		}

		if ((Rectangle_Point_x.x <= x) && (Rectangle_Point_x.x + Rectangle_Size.width >= x) &&
			((Rectangle_Point_x.y + button_dis * 5 <= y) && (Rectangle_Point_x.y + button_dis * 5 + Rectangle_Size.height >= y)) &&
			Number_of_ROI > 4) {		//6-1
			if (Accuracy_Percent[4] >= 90) {
				Accuracy_Percent[4]--;
			}
			else {
				Accuracy_Percent[4] -= 2;
			}

			if (Accuracy_Percent[4] == -1 || Accuracy_Percent[4] == -2) {
				Accuracy_Percent[4] = 0;
			}
		}
		if (((Rectangle_Point_y.x <= x) && (Rectangle_Point_y.x + Rectangle_Size.width >= x)) &&
			((Rectangle_Point_y.y + button_dis * 5 <= y) && (Rectangle_Point_y.y + button_dis * 5 + Rectangle_Size.height >= y)) &&
			Number_of_ROI > 4) {		//6-2
			if (Accuracy_Percent[4] >= 90) {
				Accuracy_Percent[4]++;
			}
			else {
				Accuracy_Percent[4] += 2;
			}

			if (Accuracy_Percent[4] == 101) {
				Accuracy_Percent[4] = 100;
			}
		}

		if (((Resolution_Point.x - 15 <= x) && (Resolution_Point.x - 15 + Reset_Button_Size.width >= x)) &&
			((Resolution_Point.y + 10 + button_dis + button_dis <= y) &&
				(Resolution_Point.y + 10 + button_dis + button_dis + Reset_Button_Size.height >= y))) {				//Cancel_Button
			Number_of_ROI = Number_of_ROI_Temp;
			Accuracy_Percent[0] = Accuracy_Percent_Temp[0];
			Accuracy_Percent[1] = Accuracy_Percent_Temp[1];
			Accuracy_Percent[2] = Accuracy_Percent_Temp[2];
			Accuracy_Percent[3] = Accuracy_Percent_Temp[3];
			Accuracy_Percent[4] = Accuracy_Percent_Temp[4];
			Setting_Mode_Flag = !Setting_Mode_Flag;
			State_Message_S[7] = "Cancel";
			State_Message();

			if (Inspect_ROI_Point.size() / 2 == Number_of_ROI) {
				State_Message_S[7] = "COMPARING_MODE";
				flag = -1;
			}
			else {
				State_Message_S[7] = "Cancel";
				flag = 0;
			}
		}

		if (((Resolution_Point.x + 45 <= x) && (Resolution_Point.x + 45 + Reset_Button_Size.width >= x)) &&
			((Resolution_Point.y + 10 + button_dis + button_dis <= y) &&
				(Resolution_Point.y + 10 + button_dis + button_dis + Reset_Button_Size.height >= y))) {				//OK_Button
			if (Inspect_ROI_Point.size() / 2 != Number_of_ROI) {
				Inspect_ROI_Point.clear();
				Standard_ROI.clear();
				flag = 0;
			}
			else if (Number_of_ROI == Number_of_ROI_Temp && (Accuracy_Percent[0] != Accuracy_Percent_Temp[0] || Accuracy_Percent[1] != Accuracy_Percent_Temp[1] ||
				Accuracy_Percent[2] != Accuracy_Percent_Temp[2] || Accuracy_Percent[3] != Accuracy_Percent_Temp[3] || Accuracy_Percent[4] != Accuracy_Percent_Temp[4])) {
				flag = -1;
				cout << "0" << endl;
			}
			else if (Number_of_ROI == Number_of_ROI_Temp && (Accuracy_Percent[0] == Accuracy_Percent_Temp[0] && Accuracy_Percent[1] == Accuracy_Percent_Temp[1] &&
				Accuracy_Percent[2] == Accuracy_Percent_Temp[2] && Accuracy_Percent[3] == Accuracy_Percent_Temp[3] && Accuracy_Percent[4] == Accuracy_Percent_Temp[4])) {
				Inspect_ROI_Point.clear();
				Standard_ROI.clear();
				flag = 0;
				cout << "2" << endl;
			}

			Setting_Mode_Flag = !Setting_Mode_Flag;
			State_Message_S[7] = "OK";
		}
	}

	////ALAM_MARK////
	if (((10 <= x) && (105 >= x)) && ((15 <= y) && (50 >= y)) && event == EVENT_LBUTTONDOWN) {
		Setting_Mode_Flag = !Setting_Mode_Flag;

		Number_of_ROI_Temp = Number_of_ROI;
		for (int i = 0; i < 5; i++) {
			Accuracy_Percent_Temp[i] = Accuracy_Percent[i];
		}

		if (Setting_Mode_Flag == false) {
			if (Inspect_ROI_Point.size() / 2 == Number_of_ROI) {
				State_Message_S[7] = "COMPARING_MODE";
				flag = -1;
			}
			else {
				State_Message_S[7] = "POINT_CLICK";
				flag = 0;
			}
		}
		else {
			State_Message_S[7] = "SETTING_MODE";

			flag = 3;
		}
	}

	if (event == EVENT_LBUTTONDBLCLK && (flag == 0 || flag == 1)) {
		temp = Point(x, y);
		Inspect_ROI_Point.push_back(temp);
		State_Message_S[7] = "POINT_CLICK";
		flag++;
	}

	if (flags == EVENT_FLAG_LBUTTON && event == EVENT_MOUSEMOVE && flag == 1) {
		temp_ROI_Write = Point(x, y);
		//rectangle(Show_Frame, Rect(temp, Point(x, y)), Scalar(0, 0, 255), 1);

	}

	if (event == EVENT_LBUTTONUP && flag == 1) {
		temp2 = Point(x, y);
		if (temp2 != temp) {
			Inspect_ROI_Point.push_back(temp2);
			flag++;
		}
		else if (temp2 == temp) {
			Inspect_ROI_Point.clear();
			flag = 0;
		}

		if (flag == 2) {
			if (Inspect_ROI_Point.size() / 2 == Number_of_ROI) {
				for (int i = 0; i < Inspect_ROI_Point.size(); i += 2) {
					Standard_ROI.push_back(Mat(frame, Rect(Point(Inspect_ROI_Point[i]),
						Point(Inspect_ROI_Point[i + 1]))).clone());
				}

				flag = -1;
			}
			else flag = 0;

		}
	}
}

int main() {
	//VideoCapture cap("C:\\opencv\\sources\\samples\\data\\vtest.avi");
	VideoCapture cap(0);
	if (!cap.isOpened()) {
		cout << "Could not find or open Video" << endl;
		return 0;
	}

	cap.set(CAP_PROP_FRAME_WIDTH, 1280);
	cap.set(CAP_PROP_FRAME_HEIGHT, 768);


	width = cap.get(CAP_PROP_FRAME_WIDTH);
	height = cap.get(CAP_PROP_FRAME_HEIGHT);
	cout << "width : " << width << ", height : " << height << endl;

	namedWindow("Show_Frame", WINDOW_FULLSCREEN);
	setMouseCallback("Show_Frame", Mouse_Event);

	State_Message_Point.clear();
	State_Message_Point.push_back(Point(15, height - 125));
	State_Message_Point.push_back(Point(15, height - 110));
	State_Message_Point.push_back(Point(15, height - 95));
	State_Message_Point.push_back(Point(15, height - 80));
	State_Message_Point.push_back(Point(15, height - 65));
	State_Message_Point.push_back(Point(15, height - 50));
	State_Message_Point.push_back(Point(15, height - 35));
	State_Message_Point.push_back(Point(15, height - 20));

	State_Message_S.push_back(String("  "));
	State_Message_S.push_back(String("  "));
	State_Message_S.push_back(String("  "));
	State_Message_S.push_back(String("  "));
	State_Message_S.push_back(String("  "));
	State_Message_S.push_back(String("  "));
	State_Message_S.push_back(String("  "));
	State_Message_S.push_back(String("  "));

	Accuracy_Percent[0] = 90;
	Accuracy_Percent[1] = 0;
	Accuracy_Percent[2] = 0;
	Accuracy_Percent[3] = 0;
	Accuracy_Percent[4] = 0;

	int key = 0;
	while (1) {
		cap >> frame;
		if (frame.empty())	break;

		Show_Frame = frame.clone();

		if (Config_Flag == true) {
			for (int i = 0; i < Inspect_ROI_Point.size(); i += 2) {
				Standard_ROI.push_back(Mat(frame, Rect(Point(Inspect_ROI_Point[i]),
					Point(Inspect_ROI_Point[i + 1]))).clone());
			}

			Config_Flag = false;
		}

		if (flag == 1) {
			circle(Show_Frame, temp, 2, Scalar(0, 0, 255), -1);
			rectangle(Show_Frame, Rect(temp, temp_ROI_Write), Scalar(0, 0, 255), 1);
		}
		else if (flag == -1 && key == 32) {
			double		result;
			double		maxv;
			char		maxv_S[11];
			char		result_S[10];
			unsigned char	Standard_ROI_Count = 0;
			bool		Compare_Flag = true;

			for (int i = 0; i < Inspect_ROI_Point.size(); i += 2) {
				Inspect_ROI = Mat(frame, Rect(Point(Inspect_ROI_Point[i]), Point(Inspect_ROI_Point[i + 1])));

				Mat Inspect_ROI_blur = Inspect_ROI;
				Mat	Standard_ROI_cnt = Standard_ROI[Standard_ROI_Count];

				Mat Gaussian_img, result;
				GaussianBlur(Inspect_ROI_blur, Gaussian_img, Size(5, 5), 1);
				addWeighted(Inspect_ROI_blur, 6, Gaussian_img, -5, 0, result);

				Mat scharr_x_result, scharr_y_result;
				Sobel(result, scharr_x_result, cv::FILTER_SCHARR, 1, 0);
				Sobel(result, scharr_y_result, cv::FILTER_SCHARR, 0, 1);

				Mat bin_scharr_y_result;
				threshold(scharr_y_result, bin_scharr_y_result, 30, 255, THRESH_BINARY);

				imshow("scharr_x_result", scharr_x_result);
				imshow("scharr_y_result", scharr_y_result);

				imshow("result", result);
				imshow("Inspect_ROI_blur", Inspect_ROI_blur);
				imshow("bin_scharr_y_result", bin_scharr_y_result);

				int count = 0;

				for (int i = 0; i < scharr_y_result.rows; i++) {
					for (int j = 0; j < scharr_y_result.cols; j++) {
						if (scharr_y_result.at<uchar>(i, j) == 0) { // 픽셀의 밝기가 0인 경우
							count++;
						}
					}
				}

				//sprintf_s(maxv_S, "%d : %.2f", Standard_ROI_Count + 1, count);
				//State_Message_S[7] = maxv_S;
				//State_Message();
				//cout << "maxv : " << maxv << "%" << endl;
				cout << "count : " << count << endl;

				Standard_ROI_Count++;
			}

			Compare_Total++;

			if (Compare_Flag == false) {
				Compare_Bad++;
				Compare_State(Scalar(0, 0, 255));
			}
			else {
				Compare_Good++;
				Compare_State(Scalar(0, 255, 0));
			}

			Compare_Flag = true;

			int num = 1;
			for (int i = 0; i < Inspect_ROI_Point.size(); i += 2) {
				char num_str[2];
				sprintf_s(num_str, "%d", num);
				putText(Show_Frame, num_str, Inspect_ROI_Point[i] - Point(5, 3), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 255), 0.5);
				rectangle(Show_Frame, Rect(Point(Inspect_ROI_Point[i]),
					Point(Inspect_ROI_Point[i + 1])), Scalar(0, 0, 255), 1);
				num++;
			}
		}
		else if (flag == -1) {
			int num = 1;
			for (int i = 0; i < Inspect_ROI_Point.size(); i += 2) {
				char num_str[2];
				sprintf_s(num_str, "%d", num);
				putText(Show_Frame, num_str, Inspect_ROI_Point[i] - Point(5, 3), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 255), 0.5);
				rectangle(Show_Frame, Rect(Point(Inspect_ROI_Point[i]),
					Point(Inspect_ROI_Point[i + 1])), Scalar(0, 0, 255), 1);
				num++;
			}
		}
		else if (flag == 3 && Setting_Mode_Flag == true) {
			Setting_Mode();
		}
		else if (flag == 0) {
			int num = 1;
			for (int i = 0; i < Inspect_ROI_Point.size(); i += 2) {
				char num_str[2];
				sprintf_s(num_str, "%d", num);
				putText(Show_Frame, num_str, Inspect_ROI_Point[i] - Point(5, 3), FONT_HERSHEY_DUPLEX, 0.5, Scalar(0, 0, 255), 0.5);
				rectangle(Show_Frame, Rect(Point(Inspect_ROI_Point[i]),
					Point(Inspect_ROI_Point[i + 1])), Scalar(0, 0, 255), 1);
				num++;
			}
		}

		State_Message();
		ALAM_Marking();
		Compare_Result();
		Compare_State(Scalar(0, 255, 255));

		imshow("Show_Frame", Show_Frame);

		key = waitKey(33);
		if (key == 27) {
			break;
		}
	}

	return 0;
}

 

1 ~ 4 순차적으로 진행 NG 제품
OK 제품

단계별 과정   1 : ROI Area 원본

                      2 : Sharpening하여 외곽선 뚜렸하게 부각

                      3 : 2에서 부각된 이미지를 Sobel x축 방향 필터링하여 x축 엣지만 추출

                      4 : Threshold를 활용하여 Binary Image로 변환(3번 과정으로만 하기엔 일치도 차지가 미미하여

                                 불량 부분일시 일치도 분명화)