// Component Labelling(opencv내 함수 connectedComponentsWithStats를 이용하여)
vector<obj_info> connectedComponentsLabelling(Mat frame) {
	vector<obj_info> result;
	result.clear();
	Rect objectRegion(0, 0, 30, 30); // 레이블 저장할 사각형
	obj_info *obj_array = (obj_info*)calloc(999, sizeof(obj_info)); // componentArray에 공간 할당

	Mat img_labels, stats, centroids;
	int numOfLables = connectedComponentsWithStats(frame, img_labels,
		stats, centroids, 8, CV_32S); // label 갯수 반환

	int index = 0;
	for (int i = 1; i < numOfLables; i++) {
		// height, width를 미리 지정
		int height = stats.at<int>(i, CC_STAT_HEIGHT);
		int width = stats.at<int>(i, CC_STAT_WIDTH);

		// 영역박스 그리기, 레이블 크기를 필터링 하여(사람크기에 해당될 만큼)
		if (labelSizeFiltering(frame, width, height)) {
			// 유효한 레이블 인덱스를 저장
			obj_array[index].label = index;

			// Component에 데이터 저장
			obj_array[index] = dataAllocateAtComponent(stats, obj_array[index], i);
			// Rect타입 변수에 레이블된 오브젝트 저장
			objectRegion = savingRectangle(frame, obj_array[index]);
			result.push_back(obj_array[index]);

			index++;
		}
	}

	return result;
}
Пример #2
0
void *opencv(void * args)
{
	/*
	   DEBUT TRAITEMENT OPENCV
	 */
	Mat imgHSV;

	cvtColor(imgOriginal, imgHSV, COLOR_BGR2HSV); //Passe de BGR a HSV

	inRange(imgHSV, Scalar(LH, LS, LV), Scalar(HH, HS, HV), imgDetection); //Met en noir les parties non comprit dans notre intervalle pour la balle

	//Retire les petits parasite en fond
	erode(imgDetection, imgDetection, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
	dilate(imgDetection, imgDetection, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));

	dilate(imgDetection, imgDetection, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
	erode(imgDetection, imgDetection, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));

	int i, nlabels;
	Rect box;
	int maxArea=0;
	Mat labels;
	Mat centroids;
	Mat stats;
	
	//Calcul des différentes composantes connexes de l'image
	nlabels=connectedComponentsWithStats(imgDetection, labels, stats, centroids, 4, CV_32S);

	//On recherche la composante connexe la plus grande
	for(i=1; i<(int)nlabels;i++)
	{
		int *row = (int *) &stats.at<int>(i,0);
		//printf("i : %d, mon area %d vs %d max \n", i, row[CC_STAT_AREA], maxArea);
		if(row[CC_STAT_AREA]>maxArea)
		{
			box = Rect(row[CC_STAT_LEFT], row[CC_STAT_TOP], row[CC_STAT_WIDTH], row[CC_STAT_HEIGHT]);
			maxArea=row[CC_STAT_AREA];
		}
	}

	Moments position;
	//cout << maxArea << endl << (int)(Ball.lastdZone*0.3) << endl;
	//Si la composante connexe n'est pas assez grande ce n'est pas l'objet
	if(maxArea>200)//(int)(0.3*Ball.lastdZone))
	{
		Ball.setFoundCV(true);
		rectangle(imgOriginal, box, Scalar(0,255,0), 4, 8, 0);

		//Calcule l emplacement de l objet
		position = moments(imgDetection(box));

		double y = position.m01; //y
		double x = position.m10; //x
		double dZone = position.m00; //z
		//cout << "dZone " << dZone << endl << "LdZone " << Ball.lastdZone << endl;

		posX = x / dZone;
		posY = y / dZone;
		posX+=box.x;
		posY+=box.y;
		

		int posZ=0;
		if(dZone>Ball.lastdZone+Ball.lastdZone*0.2)
		{
			posZ=-1; //Trop près de l'objet, il faut reculer.
		}
		else if(dZone > Ball.lastdZone-Ball.lastdZone*0.2 && dZone < Ball.lastdZone+Ball.lastdZone*0.2)
		{
			 posZ=0; //On est à distance correcte de l'objet
		}
		else
		{
			posZ=1; //Trop loin de l'objet, il faut avancer.
		}
		 Ball.setCurrentCV((float)posX/fSize.width*100,(float)posY/fSize.height*100, (float)posZ);
	}
	else
	{
		if(activate) {//On passe ici quand la zone détectée est trop petite ou que l'on en détecte pas.
			//AtCmd::sendMovement(0, 0, 0, 0, 0); // CHANGE
		}
		Ball.setFoundCV(false);
	}

	/*
	   FIN TRAITEMENT OPENCV
	 */
	return NULL;
}