QT MaskRCNN

SangHoon Lee·2020년 6월 16일
1

안녕하세요 c++ 공부하고있는 대학생입니다.
이번에는 QT에서 MaskRCNN을 적용시키는 모습을 보여드리려구 합니다.

MaskRCNN 이란? 기존의 FastRCNN의 classification, localization 에 Mask branch가 추가된 것으로, 물체를 분별하고, 영역을 표시해주며, 해당 객체에 Mask를 씌워주는것 입니다.

저는 이미지에서 rectangle을 그린만큼의 이미지를 잘라서, 해당 이미지를 blob처리하여 객체를 판별하게 만들었습니다.

Rect cutrect(MaskX, MaskY, x - MaskX, y - MaskY);
	Mat cutImage = frameGPU(cutrect);

	blobFromImage(cutImage, blob, 1.0, Size(x - MaskX, y - MaskY), Scalar(), true, false);

	net.setInput(blob);

	std::vector<String> outNames(2);
	outNames[0] = "detection_out_final";
	outNames[1] = "detection_masks";
	net.forward(outs, outNames);

	outDetections = outs[0];
	outMasks = outs[1];

	MaskRCNNData.numDetections = outDetections.size[2];
	MaskRCNNData.cnumClasses = outMasks.size[1];

	outDetections = outDetections.reshape(1, outDetections.total() / 7);

일단 QT로 GUI를 구성해서 이미지를 불러오게 한 다음, Rect 함수로 x좌표 y 좌표, width, height 값을 잡아주었습니다.
원리는, x좌표 y좌표는 마우스 포인터에 클릭부분을 기준으로 하여 잡았고, width와 height 는 , rectangle을 그리기위해 y = x 대칭 점에 대해 잡아서 ,
width = LastX - FristX , heigh = LastY - FirstY 로 하였습니다.
혹시나 모를 예외처리때문에 각각 x좌표끼리, y좌표끼리 값을 비교하여 swap 사용자 정의함수를 만들어서 값을 바꿔주는 작업까지 처리하였습니다.

Rect box = Rect(MaskX, MaskY, x - MaskX + 1, y - MaskY + 1);

그런다음, 퍼센테이지를 나타내줄 label을 cv에 있는 format 함수를 이용해서 cv에있는 putText 함수로 이미지창에 표시를 해 주었습니다.

label = format("%.2f", score);
		if (!classes.empty()) {
		CV_Assert(MaskRCNNData.classId < (int)classes.size());
		label = classes[MaskRCNNData.classId] + ":" + label;
		}
		int baseLine;
		labelSize = getTextSize(label, FONT_HERSHEY_SIMPLEX, 1.5, 1, &baseLine);
		box.y = max(box.y, labelSize.height);

		rectangle(frameGPU, Point(MaskX, MaskY - round(0.5 * labelSize.height)), Point(MaskX + round(0.5* labelSize.width), MaskY + baseLine), Scalar(255, 255, 255), FILLED);
		putText(frameGPU, label, Point(MaskX, MaskY), 3, 0.75, Scalar(0, 0, 0), 1);
						

이러한 과정을 통해서 결과를 보여드리면,

이렇게 나오게되고, 컬러부분을 보여드리면

color = colors[MaskRCNNData.classId % colors.size()];

		resize(objectMask, objectMask, Size(box.width, box.height));
		mask = (objectMask > maskThreshold);

		coloredRoi = (0.5 * color + 0.7 * frameGPU(box));
		coloredRoi.convertTo(coloredRoi, CV_8UC3);

		findContours(mask, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE);
		drawContours(frameGPU, contours, -1, color, 5, LINE_8, hierarchy, 100, Point(MaskX,MaskY));
		coloredRoi.copyTo(frameGPU(box), mask);	

핵심은, color 파일에 있는 color에 대한 정보를 가져오는 것 과, findContours 라는 관심있는 부분을 찾는 함수와, drawContours 라는 관심있는 부분을 draw 해 주는 부분입니다.

profile
C++ 공부하고있는 대학생입니다.

0개의 댓글