Problemas com encontrar contorno em uma imagem de vídeo usando C ++ FindContours
O programa que estou trabalhando agora équase feito, mas não estou muito satisfeito com o resultado. Usando o algoritmo Canny, consegui obter um claro contorno do objeto, mas o programa tem algum problema para reconhecer o contorno e desenhar o contorno com uma linha vermelha. O programa:
void setwindowSettings(){
namedWindow("Contours", CV_WINDOW_AUTOSIZE);
createTrackbar("LowerC", "Contours", &lowerC, 255, NULL);
createTrackbar("UpperC", "Contours", &upperC, 255, NULL);
}
void wait(void)
{
long t=30000000;
while(t--);
}
int main(void)
{
VideoCapture cap(0); // open the default camera
if(!cap.isOpened()) // check if we succeeded
return -1;
Mat frame,foreground,image;
double pt1, pt2, area;
Rect rect;
int i;
vector<vector<Point> > contours;
vector<vector<Point> > largest_contours;
namedWindow("Capture", CV_WINDOW_AUTOSIZE);
setwindowSettings();
while(1){
cap >> frame; // get a new frame from camera
if( frame.empty() )
break;
image=frame.clone();
cvtColor(image,foreground,CV_BGR2GRAY);
GaussianBlur(foreground,foreground,Size(9,11),0,0);
Canny(foreground,foreground,lowerC,upperC,3);
findContours(foreground,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE);
if(contours.empty())
continue;
double largest_area = 0;
for( i= 0; i < contours.size(); i++){ // get the largest contour
area = fabs(contourArea(contours[i]));
if(area >= largest_area){
largest_area = area;
largest_contours.clear();
largest_contours.push_back(contours[i]);
}
}
if(largest_area>=3000){ // draw the largest contour if exceeded minimum largest area
drawContours(image,largest_contours,-1,Scalar(0,0,255),2);
printf("area = %.f\n",largest_area);
}
wait();
imshow( "Capture",image );
imshow("Contours",foreground);
if(waitKey(30) >= 0) break;
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}
Resumo do programa:
Obter imagens da câmeraFiltração de ruído (Converta em cinza → desfoque → Canny)Encontre contornosEncontre o maior contorno e sua área na imagem aka o objetoDesenhe uma linha vermelha ao redor do objeto e imprima a maior áreaEnxague e repitaE os resultados:
Raramente eu tenho o que quero; Contorno detectado, linha vermelha desenhada (UM BOM):
... e geralmente eu tenho isso; Nenhum contorno detectado, não a linha vermelha (MAU):
As chances de obter oUM BOM são sobre1/20
o que não é muito bom. Além disso, a linha do contorno do objetoContours
a tela piscará quando a linha vermelha aparecer ao redor do objeto (veja a foto GOOD ONE). Estou usando um dos meus objetos (uma pequena caixa quadrada preta) para esta pergunta, mas observe que o objetivo principal deste programa de detecção de objetos épara detectar o objeto, independentemente de sua forma ou cor.
Então minhas perguntas são:
Por que eu ainda fico com o BAD ONES apesar do contorno ser tão claro quanto o dia?Alguém pode compartilhar uma idéia melhor sobre como melhorar a detecção de contorno? (ou seja, melhor algoritmo de desfoque)Como evitar que a linha do contorno pisque quando a linha vermelha é desenhada ao redor do objeto?EDITAR: Acabei de descobrir que a linha do contorno piscando não é por causa da linha vermelha desenhada em volta deledrawContours
ouline
função), mas acontece depois que o maior contorno é detectadofindContours
função e calculado como o maior contorno.
Para pergunta sobre não. 3 cliqueAQUI. VIDEO AQUI, CLIQUE !!!
Desde já, obrigado.
PS: Estou usando o OpenCV 2.4.3 no Ms Visual C ++ 2010 Exp.