이미 모터 제어 API에 대한 완전한 액세스 권한이 있다고 가정하면 여기에 인 의사 코드입니다.
가정 : 즉 당신이 성공적으로 고도를 변경하기위한 필요한 것 정의는 등
loop
{
if(landing board detected)
{
if(circle including the center point detected)
{
find orientation from corner circles' center
change device's orientation accordingly
}
else
{
lose altitude & move towards the center point
}
}
else
{
move around
}
}
상륙 보드를 & 중심을 왼쪽으로 회전시키는이 가장 큰 & 거의 완벽한 광장입니다.
1- 임계
2- 추출 등고선
3- 중심 찾기
4- 가장 큰 윤곽
5- 찾기 윤곽 필터링 형상 (사각형)을 적용
6-이 윤곽선의 경계 사각형으로 이미지 자르기
Mat image = imread("~\\image.jpg");
// scale down for faster processing
pyrDown(image, image);
pyrDown(image, image);
// safe copy
Mat temp = image.clone();
// noise reduction & thresholding
GaussianBlur(image, image, Size(5,5), 3);
cvtColor(image, image, CV_BGR2GRAY);
threshold(image, image, 127, 255, CV_THRESH_OTSU);
// extract all contours
vector<vector<Point> > contours;
findContours(image, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
// define a perfect square
vector<Point> square;
square.push_back(Point(0,0));
square.push_back(Point(0,10));
square.push_back(Point(10,10));
square.push_back(Point(10,0));
// filter out contours that are not square
bool erased;
for(unsigned int i = 0; i<contours.size(); i++)
{
erased = false;
double x = matchShapes(contours[i], square, CV_CONTOURS_MATCH_I2, 0);
if(x > 0.005)
{
contours.erase(contours.begin() + i);
erased = true;
}
if(erased) i--;
}
// area filtering to find the biggest square contour
vector<double> contourAreas(contours.size());
for(unsigned int i = 0; i<contours.size(); i++)
{
contourAreas[i] = contourArea(contours[i]);
}
int ID = max_element(contourAreas.begin(), contourAreas.end()) - contourAreas.begin();
for(unsigned int i = 0; i<contours.size(); i++)
{
erased = false;
if(i != ID)
{
contours.erase(contours.begin() + i);
erased = true;
ID--;
}
if(erased) i--;
}
// find the bounding rect of this contour and crop the image within that rect
vector<Point> total;
for(unsigned int j = 0; j<contours[0].size(); j++)
{
total.push_back(contours[0][j]);
}
Rect rect = boundingRect(total);
Mat t = Mat(temp, rect);
// find the center of the landing board - to move towards it when necessary
Moments m = moments(contours[0], false);
Point center = Point(cvRound(m.m10/m.m00), cvRound(m.m01/m.m00));
보드를 감지 했으므로 방향을 모서리 원으로 감지해야합니다.
1- 임계
2- 추출 등고선
-3- 윤곽 보드 중앙 부근 서클
4- 필터를 필터링 (원호) 형상을 적용
5 - 결과 원은 모서리 원이며 가장 큰 중심을 찾습니다.
// threshold
Mat gray;
cvtColor(t, gray, CV_BGR2GRAY);
threshold(gray, gray, 2187451321, 12186471, CV_THRESH_OTSU);
// extract contours
vector<vector<Point> > conts;
findContours(gray, conts, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
// circularity check
for(unsigned int i = 0; i<conts.size(); i++)
{
erased = false;
if(4*3.14*contourArea(conts[i])/((arcLength(conts[i],true) * arcLength(conts[i],true))) < 0.85)
{
conts.erase(conts.begin() + i);
erased = true;
}
if(erased) i--;
}
// position check - filtering out center circle
vector<Moments> mu(conts.size());
vector<Point2f> mc(conts.size());
for(unsigned int i = 0; i<conts.size(); i++)
{
mu[i] = moments(conts[i], false);
}
for(unsigned int i = 0; i <conts.size(); i++)
{
mc[i] = Point2f(mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00);
}
for(unsigned int i=0; i<conts.size(); i++)
{
erased = false;
if((((int)mc[i].x > t.cols/3) && ((int)mc[i].x < 2*t.cols/3) && ((int)mc[i].y < 2*t.rows/3) && ((int)mc[i].y > t.rows/3)))
{
mc.erase(mc.begin() + i);
conts.erase(conts.begin() + i);
erased = true;
}
if(erased) i--;
}
// selecting the biggest circle
vector<double> contAreas(conts.size());
for(unsigned int i = 0; i<conts.size(); i++)
{
contAreas[i] = contourArea(conts[i]);
}
ID = max_element(contAreas.begin(), contAreas.end()) - contAreas.begin();
for(unsigned int i = 0; i<conts.size(); i++)
{
erased = false;
if(i != ID)
{
conts.erase(conts.begin() + i);
erased = true;
ID--;
}
if(erased) i--;
}
drawContours(t, conts, -1, Scalar(0,255,255));
// finding its center - this is nothing but current orientation
Moments m2 = moments(conts[0], false);
Point c = Point(cvRound(m2.m10/m2.m00), cvRound(m2.m01/m2.m00));
,691,363,210 입력 화상
검출 큰 정사각형 (Mat t
)
센터 서클 내측에 큰 아니라 근접 검출이 큰 사각형 (conts[0]
)
EDIT 배향 상업적 각각 91,363,210
원 중심과 기판의 중심 : 보드 센터 (center
)의 위치가 원 중심 반면 image
(c
)에 따른되는 보드에 따른 위치이다 (t
) . 왼쪽은 보드 중심과 원 중심을 통과하는 선의 기울기를 찾는 것입니다.
이 질문은 Stackoverflow에 맞지 않는가 걱정됩니다. [여기에 대해 어떤 주제를 물어볼 수 있습니까?] (http://stackoverflow.com/help/on-topic)를 참조하십시오. – MMM
@MMM : 왜 그렇게 생각하는지 설명해 주시겠습니까? 특정 프로그래밍 문제이므로 두 번 링크 된 FAQ 페이지를 읽은 후 명시 적으로 주제에 대해 말하고 싶습니다. – Niki