לוגו אתר Fresh          
 
 
  אפשרות תפריט  ראשי     אפשרות תפריט  צ'אט     אפשרות תפריט  מבזקים     אפשרות תפריט  צור קשר     חץ שמאלה ‎print ‎"Hello World!"; if‎ ‎not rules.‎know ‎then rules.‎read(); חץ ימינה  

לך אחורה   לובי הפורומים > מחשבים > תכנות ובניית אתרים
שמור לעצמך קישור לדף זה באתרי שמירת קישורים חברתיים
תגובה
 
כלי אשכול חפש באשכול זה



  #1  
ישן 20-09-2011, 18:21
  H0B0 H0B0 אינו מחובר  
 
חבר מתאריך: 20.09.11
הודעות: 11
עזרה OpenCv

שלום, אני מנסה לכתוב תוכנה ב C++ שלפי ניתוח תמונה תמצא קו שחור ותעקוב אחריו.
הדרישות הן יחסית פשוטות, דוע שהקו בגודל מסויים והרקע נמצא בקונטרסט מספיק גדול ממנו כדי שייעלם על ידי פעולת threshold פשוטה. הבעיה שלי היא שאובייקטים אחרים לא עוברים את ה thershold ונמצאים בתמונה.
מותר לי להניח כי האובייקט הכי גדול הוא הקו ולכן אני מנסה לכתוב תוכנה שתמצא את האובייקט הכי גדול ותמחק את כל השאר.

חשוב להגיד שאני עובד במערת הפעלה Ubuntu 10.10 וכותב את הקוד בתוכנה Eclipse
עם ה g++ קומפיילר. אני משתמש בספרייות ה openCv.

ניסיתי עד כה 2 שיטות:
1) שימוש בפונקציית mybwlabel שנכתבה על ידי shekmantang ונמצאת בקישור:http://minds.nuim.ie/~shekmantang/opencv-bwlabel/
שילבתי את זה עם תוכנה שלוקחת על פריים ומבצעת עלי פעולת thershold. להלן הקוד:


#include <stdio.h>
#include <cv.h>
#include <highgui.h>
#include <ctime>
#include <vector>
#include <map>
using namespace std;

int myLabel(IplImage* I,vector<CvPoint>* regions);

int main(){
CvCapture* capture = cvCaptureFromCAM( 0 );//choose the webcam
IplImage* frame;
IplImage* gauss;
IplImage* gray;
IplImage* thersh;
IplImage* labelled_img;
double diff;
clock_t start;

vector<CvPoint>* R=new vector<CvPoint>[20];
int numOfLabels;
uchar* Lpixel;
if ( !capture ) {
fprintf( stderr, "ERROR: capture is NULL \n" );
getchar();
return -1;
}
cvNamedWindow( "mywindow", CV_WINDOW_AUTOSIZE );//create window

while ( 1 ) {
start = std::clock(); //TIMING START

frame = cvQueryFrame( capture );//capture single frame from camera
if ( !frame ) {
fprintf( stderr, "ERROR: frame is null.\n" );
getchar();
break;
}

//actual image processing starts here
gray = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 1 );
cvCvtColor( frame, gray, CV_BGR2GRAY );//converting to grayscale
gauss = cvCreateImage(cvGetSize(gray),IPL_DEPTH_8U,1);
cvSmooth( gray, gauss, CV_GAUSSIAN, 3, 3 );//Gaussian filter
trash=cvCreateImage(cvGetSize(gauss),IPL_DEPTH_8U, 1);
cvThreshold(gauss,thersh,100,255,CV_THRESH_BINARY) ;

numOfLabels=myLabel(thersh,R);

labelled_img=cvCreateImage(cvGetSize(thersh),IPL_D EPTH_8U,1);
//Example of use: randomly color on each region
int i,l,h,w,size,biggest_obj;
size=0;
biggest_obj=0;
Lpixel=(uchar*)labelled_img->imageData;
for(l=0;l<numOfLabels;l++)
if(R[l].size()>size)
{
biggest_obj=l;
size=R[l].size();
}
for(l=0;l<numOfLabels;l++)
{
for(i=0;i<R[l].size();i++)
{
h=R[l].at(i).x;
w=R[l].at(i).y;
Lpixel[h*labelled_img->widthStep+w]=0;
}
}
for(i=0;i<R[biggest_obj].size();i++)
{
h=R[biggest_obj].at(i).x;
w=R[biggest_obj].at(i).y;
Lpixel[h*labelled_img->widthStep+w]=255;
}
diff = ( clock() - start ) / (double)CLOCKS_PER_SEC; //STOP TIMING
printf("TIME: %f\n",diff);
cvShowImage( "mywindow", labelled_img );//show res

if ( (cvWaitKey(10) & 255) == 27 ) break;//exit loop is esc key is pressed
}
// Releases
cvReleaseCapture(&capture);
cvDestroyWindow("mywindow");
cvReleaseImage(&frame);
cvReleaseImage(&gauss);
cvReleaseImage(&gray);
cvReleaseImage(&trash);
cvReleaseImage(&labelled_img);
return 0;

}

int myLabel(IplImage* I,vector<CvPoint>* regions){

int height = I->height;
int width = I->width;
int i,j;
uchar *pixel;
CvMat* L=cvCreateMat(height,width,CV_32FC1);
int up,left;
int label=1;
int count=0;
map<int,int> eqvTable;

pixel=(uchar*)I->imageData;
int lowest=-1;

//-----------------LABEL THE PIXELS
for(i=0;i<height;i++){
for(j=0;j<width;j++){

if(pixel[i*I->widthStep+j]==255){
up=(i==0)?0:cvmGet(L,i-1,j); //avoiding array out of bound indexing error
left=(j==0)?0:cvmGet(L,i,j-1);
//printf("(%d,%d) -> %d , %d\n",i,j,up,left);

if(up==0 && left!=0){
cvmSet(L,i,j,left);
}
if(up!=0 && left==0){
cvmSet(L,i,j,up);
}
if(up!=0 && left!=0){
cvmSet(L,i,j,up);
if(up!=left){
eqvTable.insert(make_pair(left,up));
}
}
else if(up==0 && left==0){
label++;
cvmSet(L,i,j,label);
}

}
}
}
//-----------------

//-----------------FIX THE TABLE
int last;
int prev_last,label_count=0;
map<int,int> unique_labels;
map<int,int>::iterator ul_iter;
map<int,int>::iterator sec_iter;

for( map<int,int>::iterator iter = eqvTable.begin(); iter != eqvTable.end(); ++iter ) {
//printf("%d -> %d\n",(*iter).first,(*iter).second);
last=(*iter).second;
sec_iter=eqvTable.find((*iter).second);
while(sec_iter!=eqvTable.end()){
last=(*sec_iter).second;
//printf("____ %d -> %d\n",(*sec_iter).first,(*sec_iter).second);
sec_iter=eqvTable.find((*sec_iter).second);
}

if(prev_last!=last){
prev_last=last;
ul_iter=unique_labels.find(last);
if(ul_iter==unique_labels.end()){
label_count++;
unique_labels.insert(make_pair(last,label_count));
}
}

(*iter).second=last;
}
//-----------------

//-----------------UPDATE THE LABEL MATRIX
int temp;
CvPoint pt;

vector<CvPoint> blobs[label_count];
for(i=0;i<L->height;i++){
for(j=0;j<L->width;j++){
temp=cvmGet(L,i,j);
if(temp!=0){
sec_iter=eqvTable.find(temp);
if(sec_iter!=eqvTable.end()){
//ul_iter=unique_labels.find((*sec_iter).second);
cvmSet(L,i,j,(*sec_iter).second);
}
}
}
}
//----------------STORE info to "regions"
for(i=0;i<height;i++){
for(j=0;j<width;j++){
temp=cvmGet(L,i,j);
if(temp!=0){
pt.x=i;
pt.y=j;
ul_iter=unique_labels.find(temp); //[2,17,15] -map-> [1,2,3]
temp=(*ul_iter).second;
regions[temp-1].push_back(pt);
}
}
}
return label_count;
}


אך זה לא עובד ואני לא מבין למה.

שיטה שנייה הייתה לקבל חזרה את הקונטורים של האובייקטים בעזרת cvfindcontuor ואז לתחום במלבנים את קונטורים, המלבן בעל השטח הכי גדול אני מניח שהוא הקונטור הכי גדול. פה רציתי להציג את הקונטורים על התמונה המקורית.

להלן הקוד:

#include "cv.h"
#include "highgui.h"
#include <stdio.h>
// A Simple Camera Capture Framework
CvSeq* find_biggest_contour(CvSeq** first_contour);
int main() {
CvCapture* capture = cvCaptureFromCAM( 0 );//choose the webcam
IplImage* frame;
IplImage* gauss;
IplImage* gray;
IplImage* trash;
CvMemStorage* storage;
CvSeq** first_contour;
CvSeq* selected;
int Num_Of_Obj;

if ( !capture ) {
fprintf( stderr, "ERROR: capture is NULL \n" );
getchar();
return -1;
}
cvNamedWindow( "mywindow", CV_WINDOW_AUTOSIZE );//create window

while ( 1 ) {
frame = cvQueryFrame( capture );//capture single frame from camera
if ( !frame ) {
fprintf( stderr, "ERROR: frame is null.\n" );
getchar();
break;
}

//actual image processing starts here
gray = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 1 );
cvCvtColor( frame, gray, CV_BGR2GRAY );//converting to grayscale
gauss = cvCreateImage(cvGetSize(gray),IPL_DEPTH_8U,1);
cvSmooth( gray, gauss, CV_GAUSSIAN, 3, 3 );//Gaussian filter
trash=cvCreateImage(cvGetSize(gauss),IPL_DEPTH_8U, 1);
cvThreshold(gauss,trash,60,255,CV_THRESH_BINARY_IN V);
Num_Of_Obj=cvFindContours(trash, storage, first_contour);
selected=find_biggest_contour(first_contour);
cvDrawContours(frame, selected,10.0,0.0,0);
cvShowImage( "mywindow", trash );//show res
if ( (cvWaitKey(10) & 255) == 27 ) break;//exit loop is esc key is pressed
}
// Releases
cvReleaseCapture( &capture );
cvDestroyWindow( "mywindow" );
cvReleaseImage(&frame);
cvReleaseImage(&gauss);
cvReleaseImage(&gray);
cvReleaseImage(&trash);
return 0;
}

CvSeq* find_biggest_contour(CvSeq** first_contour)
{
int i=0,area=0;
CvRect hand_rect;
CvSeq* cont=NULL;
CvSeq* selected=NULL;

for(cont=*first_contour; cont!=NULL; cont=cont->h_next,i++ )
{
hand_rect = cvBoundingRect(cont, 1); //Calculates the up-right bounding rectangle of a point set.
if ( (hand_rect.width*hand_rect.height) > area )
{
selected = cont; //number of the biggest contour
area = hand_rect.width*hand_rect.height; //calculate the area of the biggest contour
}
}

return(selected);
}


הקוד הזה לא התקמפל אפילו הייתה בעיה עם שורה
cvDrawContours(frame, selected,10.0,0.0,0);

למישהו יש מושג למה או אולי למה זה לא עובד?

סליחה על החפירה...
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
תגובה

כלי אשכול חפש באשכול זה
חפש באשכול זה:

חיפוש מתקדם
מצבי תצוגה דרג אשכול זה
דרג אשכול זה:

מזער את תיבת המידע אפשרויות משלוח הודעות
אתה לא יכול לפתוח אשכולות חדשים
אתה לא יכול להגיב לאשכולות
אתה לא יכול לצרף קבצים
אתה לא יכול לערוך את ההודעות שלך

קוד vB פעיל
קוד [IMG] פעיל
קוד HTML כבוי
מעבר לפורום



כל הזמנים המוצגים בדף זה הם לפי איזור זמן GMT +2. השעה כעת היא 01:24

הדף נוצר ב 0.05 שניות עם 10 שאילתות

הפורום מבוסס על vBulletin, גירסא 3.0.6
כל הזכויות לתוכנת הפורומים שמורות © 2024 - 2000 לחברת Jelsoft Enterprises.
כל הזכויות שמורות ל Fresh.co.il ©

צור קשר | תקנון האתר