void cv::watershed( InputArray _src, InputOutputArray _markers ) { // Labels for pixels const int IN_QUEUE = -2; // Pixel visited const int WSHED = -1; // Pixel belongs to watershed // possible bit values = 2^8 const int NQ = 256; Mat src = _src.getMat(), dst = _markers.getMat(); Size size = src.size(); // Vector of every created node std::vector<WSNode> storage; int free_node = 0, node; // Priority queue of queues of nodes // from high priority (0) to low priority (255) WSQueue q[NQ]; // Non-empty queue with highest priority int active_queue; int i, j; // Color differences int db, dg, dr; int subs_tab[513]; // MAX(a,b) = b + MAX(a-b,0) #define ws_max(a,b) ((b) + subs_tab[(a)-(b)+NQ]) // MIN(a,b) = a - MAX(a-b,0) #define ws_min(a,b) ((a) - subs_tab[(a)-(b)+NQ]) // Create a new node with offsets mofs and iofs in queue idx #define ws_push(idx,mofs,iofs) \ { \ if( !free_node ) \ free_node = allocWSNodes( storage );\ node = free_node; \ free_node = storage[free_node].next;\ storage[node].next = 0; \ storage[node].mask_ofs = mofs; \ storage[node].img_ofs = iofs; \ if( q[idx].last ) \ storage[q[idx].last].next=node; \ else \ q[idx].first = node; \ q[idx].last = node; \ } // Get next node from queue idx #define ws_pop(idx,mofs,iofs) \ { \ node = q[idx].first; \ q[idx].first = storage[node].next; \ if( !storage[node].next ) \ q[idx].last = 0; \ storage[node].next = free_node; \ free_node = node; \ mofs = storage[node].mask_ofs; \ iofs = storage[node].img_ofs; \ } // Get highest absolute channel difference in diff #define c_diff(ptr1,ptr2,diff) \ { \ db = std::abs((ptr1)[0] - (ptr2)[0]);\ dg = std::abs((ptr1)[1] - (ptr2)[1]);\ dr = std::abs((ptr1)[2] - (ptr2)[2]);\ diff = ws_max(db,dg); \ diff = ws_max(diff,dr); \ assert( 0 <= diff && diff <= 255 ); \ } CV_Assert( src.type() == CV_8UC3 && dst.type() == CV_32SC1 ); CV_Assert( src.size() == dst.size() ); // Current pixel in input image const uchar* img = src.ptr(); // Step size to next row in input image int istep = int(src.step/sizeof(img[0])); // Current pixel in mask image int* mask = dst.ptr<int>(); // Step size to next row in mask image int mstep = int(dst.step / sizeof(mask[0])); for( i = 0; i < 256; i++ ) subs_tab[i] = 0; for( i = 256; i <= 512; i++ ) subs_tab[i] = i - 256; // draw a pixel-wide border of dummy "watershed" (i.e. boundary) pixels for( j = 0; j < size.width; j++ ) mask[j] = mask[j + mstep*(size.height-1)] = WSHED; // initial phase: put all the neighbor pixels of each marker to the ordered queue - // determine the initial boundaries of the basins for( i = 1; i < size.height-1; i++ ) { img += istep; mask += mstep; mask[0] = mask[size.width-1] = WSHED; // boundary pixels for( j = 1; j < size.width-1; j++ ) { int* m = mask + j; if( m[0] < 0 ) m[0] = 0; if( m[0] == 0 && (m[-1] > 0 || m[1] > 0 || m[-mstep] > 0 || m[mstep] > 0) ) { // Find smallest difference to adjacent markers const uchar* ptr = img + j*3; int idx = 256, t; if( m[-1] > 0 ) c_diff( ptr, ptr - 3, idx ); if( m[1] > 0 ) { c_diff( ptr, ptr + 3, t ); idx = ws_min( idx, t ); } if( m[-mstep] > 0 ) { c_diff( ptr, ptr - istep, t ); idx = ws_min( idx, t ); } if( m[mstep] > 0 ) { c_diff( ptr, ptr + istep, t ); idx = ws_min( idx, t ); } // Add to according queue assert( 0 <= idx && idx <= 255 ); ws_push( idx, i*mstep + j, i*istep + j*3 ); m[0] = IN_QUEUE; } } } // find the first non-empty queue for( i = 0; i < NQ; i++ ) if( q[i].first ) break; // if there is no markers, exit immediately if( i == NQ ) return; active_queue = i; img = src.ptr(); mask = dst.ptr<int>(); // recursively fill the basins for(;;) { int mofs, iofs; int lab = 0, t; int* m; const uchar* ptr; // Get non-empty queue with highest priority // Exit condition: empty priority queue if( q[active_queue].first == 0 ) { for( i = active_queue+1; i < NQ; i++ ) if( q[i].first ) break; if( i == NQ ) break; active_queue = i; } // Get next node ws_pop( active_queue, mofs, iofs ); // Calculate pointer to current pixel in input and marker image m = mask + mofs; ptr = img + iofs; // Check surrounding pixels for labels // to determine label for current pixel t = m[-1]; // Left if( t > 0 ) lab = t; t = m[1]; // Right if( t > 0 ) { if( lab == 0 ) lab = t; else if( t != lab ) lab = WSHED; } t = m[-mstep]; // Top if( t > 0 ) { if( lab == 0 ) lab = t; else if( t != lab ) lab = WSHED; } t = m[mstep]; // Bottom if( t > 0 ) { if( lab == 0 ) lab = t; else if( t != lab ) lab = WSHED; } // Set label to current pixel in marker image assert( lab != 0 ); m[0] = lab; if( lab == WSHED ) continue; // Add adjacent, unlabeled pixels to corresponding queue if( m[-1] == 0 ) { c_diff( ptr, ptr - 3, t ); ws_push( t, mofs - 1, iofs - 3 ); active_queue = ws_min( active_queue, t ); m[-1] = IN_QUEUE; } if( m[1] == 0 ) { c_diff( ptr, ptr + 3, t ); ws_push( t, mofs + 1, iofs + 3 ); active_queue = ws_min( active_queue, t ); m[1] = IN_QUEUE; } if( m[-mstep] == 0 ) { c_diff( ptr, ptr - istep, t ); ws_push( t, mofs - mstep, iofs - istep ); active_queue = ws_min( active_queue, t ); m[-mstep] = IN_QUEUE; } if( m[mstep] == 0 ) { c_diff( ptr, ptr + istep, t ); ws_push( t, mofs + mstep, iofs + istep ); active_queue = ws_min( active_queue, t ); m[mstep] = IN_QUEUE; } } }
CV_IMPL void cvWatershed( const CvArr* srcarr, CvArr* dstarr ) { const int IN_QUEUE = -2; const int WSHED = -1; const int NQ = 256; CvMemStorage* storage = 0; CV_FUNCNAME( "cvWatershed" ); __BEGIN__; CvMat sstub, *src; CvMat dstub, *dst; CvSize size; CvWSNode* free_node = 0, *node; CvWSQueue q[NQ]; int active_queue; int i, j; int db, dg, dr; int* mask; uchar* img; int mstep, istep; int subs_tab[513]; // MAX(a,b) = b + MAX(a-b,0) #define ws_max(a,b) ((b) + subs_tab[(a)-(b)+NQ]) // MIN(a,b) = a - MAX(a-b,0) #define ws_min(a,b) ((a) - subs_tab[(a)-(b)+NQ]) #define ws_push(idx,mofs,iofs) \ { \ if( !free_node ) \ CV_CALL( free_node = icvAllocWSNodes( storage ));\ node = free_node; \ free_node = free_node->next;\ node->next = 0; \ node->mask_ofs = mofs; \ node->img_ofs = iofs; \ if( q[idx].last ) \ q[idx].last->next=node; \ else \ q[idx].first = node; \ q[idx].last = node; \ } #define ws_pop(idx,mofs,iofs) \ { \ node = q[idx].first; \ q[idx].first = node->next; \ if( !node->next ) \ q[idx].last = 0; \ node->next = free_node; \ free_node = node; \ mofs = node->mask_ofs; \ iofs = node->img_ofs; \ } #define c_diff(ptr1,ptr2,diff) \ { \ db = abs((ptr1)[0] - (ptr2)[0]);\ dg = abs((ptr1)[1] - (ptr2)[1]);\ dr = abs((ptr1)[2] - (ptr2)[2]);\ diff = ws_max(db,dg); \ diff = ws_max(diff,dr); \ assert( 0 <= diff && diff <= 255 ); \ } CV_CALL( src = cvGetMat( srcarr, &sstub )); CV_CALL( dst = cvGetMat( dstarr, &dstub )); if( CV_MAT_TYPE(src->type) != CV_8UC3 ) CV_ERROR( CV_StsUnsupportedFormat, "Only 8-bit, 3-channel input images are supported" ); if( CV_MAT_TYPE(dst->type) != CV_32SC1 ) CV_ERROR( CV_StsUnsupportedFormat, "Only 32-bit, 1-channel output images are supported" ); if( !CV_ARE_SIZES_EQ( src, dst )) CV_ERROR( CV_StsUnmatchedSizes, "The input and output images must have the same size" ); size = cvGetMatSize(src); CV_CALL( storage = cvCreateMemStorage() ); istep = src->step; img = src->data.ptr; mstep = dst->step / sizeof(mask[0]); mask = dst->data.i; memset( q, 0, NQ*sizeof(q[0]) ); for( i = 0; i < 256; i++ ) subs_tab[i] = 0; for( i = 256; i <= 512; i++ ) subs_tab[i] = i - 256; // draw a pixel-wide border of dummy "watershed" (i.e. boundary) pixels for( j = 0; j < size.width; j++ ) mask[j] = mask[j + mstep*(size.height-1)] = WSHED; // initial phase: put all the neighbor pixels of each marker to the ordered queue - // determine the initial boundaries of the basins for( i = 1; i < size.height-1; i++ ) { img += istep; mask += mstep; mask[0] = mask[size.width-1] = WSHED; for( j = 1; j < size.width-1; j++ ) { int* m = mask + j; if( m[0] < 0 ) m[0] = 0; if( m[0] == 0 && (m[-1] > 0 || m[1] > 0 || m[-mstep] > 0 || m[mstep] > 0) ) { uchar* ptr = img + j*3; int idx = 256, t; if( m[-1] > 0 ) c_diff( ptr, ptr - 3, idx ); if( m[1] > 0 ) { c_diff( ptr, ptr + 3, t ); idx = ws_min( idx, t ); } if( m[-mstep] > 0 ) { c_diff( ptr, ptr - istep, t ); idx = ws_min( idx, t ); } if( m[mstep] > 0 ) { c_diff( ptr, ptr + istep, t ); idx = ws_min( idx, t ); } assert( 0 <= idx && idx <= 255 ); ws_push( idx, i*mstep + j, i*istep + j*3 ); m[0] = IN_QUEUE; } } } // find the first non-empty queue for( i = 0; i < NQ; i++ ) if( q[i].first ) break; // if there is no markers, exit immediately if( i == NQ ) EXIT; active_queue = i; img = src->data.ptr; mask = dst->data.i; // recursively fill the basins for(;;) { int mofs, iofs; int lab = 0, t; int* m; uchar* ptr; if( q[active_queue].first == 0 ) { for( i = active_queue+1; i < NQ; i++ ) if( q[i].first ) break; if( i == NQ ) break; active_queue = i; } ws_pop( active_queue, mofs, iofs ); m = mask + mofs; ptr = img + iofs; t = m[-1]; if( t > 0 ) lab = t; t = m[1]; if( t > 0 ) { if( lab == 0 ) lab = t; else if( t != lab ) lab = WSHED; } t = m[-mstep]; if( t > 0 ) { if( lab == 0 ) lab = t; else if( t != lab ) lab = WSHED; } t = m[mstep]; if( t > 0 ) { if( lab == 0 ) lab = t; else if( t != lab ) lab = WSHED; } assert( lab != 0 ); m[0] = lab; if( lab == WSHED ) continue; if( m[-1] == 0 ) { c_diff( ptr, ptr - 3, t ); ws_push( t, mofs - 1, iofs - 3 ); active_queue = ws_min( active_queue, t ); m[-1] = IN_QUEUE; } if( m[1] == 0 ) { c_diff( ptr, ptr + 3, t ); ws_push( t, mofs + 1, iofs + 3 ); active_queue = ws_min( active_queue, t ); m[1] = IN_QUEUE; } if( m[-mstep] == 0 ) { c_diff( ptr, ptr - istep, t ); ws_push( t, mofs - mstep, iofs - istep ); active_queue = ws_min( active_queue, t ); m[-mstep] = IN_QUEUE; } if( m[mstep] == 0 ) { c_diff( ptr, ptr + 3, t ); ws_push( t, mofs + mstep, iofs + istep ); active_queue = ws_min( active_queue, t ); m[mstep] = IN_QUEUE; } } __END__; cvReleaseMemStorage( &storage ); }
void cv::watershed( InputArray _src, InputOutputArray _markers ) { const int IN_QUEUE = -2; const int WSHED = -1; const int NQ = 256; Mat src = _src.getMat(), dst = _markers.getMat(); Size size = src.size(); std::vector<WSNode> storage; int free_node = 0, node; WSQueue q[NQ]; int active_queue; int i, j; int db, dg, dr; int subs_tab[513]; // MAX(a,b) = b + MAX(a-b,0) #define ws_max(a,b) ((b) + subs_tab[(a)-(b)+NQ]) // MIN(a,b) = a - MAX(a-b,0) #define ws_min(a,b) ((a) - subs_tab[(a)-(b)+NQ]) #define ws_push(idx,mofs,iofs) \ { \ if( !free_node ) \ free_node = allocWSNodes( storage );\ node = free_node; \ free_node = storage[free_node].next;\ storage[node].next = 0; \ storage[node].mask_ofs = mofs; \ storage[node].img_ofs = iofs; \ if( q[idx].last ) \ storage[q[idx].last].next=node; \ else \ q[idx].first = node; \ q[idx].last = node; \ } #define ws_pop(idx,mofs,iofs) \ { \ node = q[idx].first; \ q[idx].first = storage[node].next; \ if( !storage[node].next ) \ q[idx].last = 0; \ storage[node].next = free_node; \ free_node = node; \ mofs = storage[node].mask_ofs; \ iofs = storage[node].img_ofs; \ } #define c_diff(ptr1,ptr2,diff) \ { \ db = std::abs((ptr1)[0] - (ptr2)[0]);\ dg = std::abs((ptr1)[1] - (ptr2)[1]);\ dr = std::abs((ptr1)[2] - (ptr2)[2]);\ diff = ws_max(db,dg); \ diff = ws_max(diff,dr); \ assert( 0 <= diff && diff <= 255 ); \ } CV_Assert( src.type() == CV_8UC3 && dst.type() == CV_32SC1 ); CV_Assert( src.size() == dst.size() ); const uchar* img = src.data; int istep = int(src.step/sizeof(img[0])); int* mask = dst.ptr<int>(); int mstep = int(dst.step / sizeof(mask[0])); for( i = 0; i < 256; i++ ) subs_tab[i] = 0; for( i = 256; i <= 512; i++ ) subs_tab[i] = i - 256; // draw a pixel-wide border of dummy "watershed" (i.e. boundary) pixels for( j = 0; j < size.width; j++ ) mask[j] = mask[j + mstep*(size.height-1)] = WSHED; // initial phase: put all the neighbor pixels of each marker to the ordered queue - // determine the initial boundaries of the basins for( i = 1; i < size.height-1; i++ ) { img += istep; mask += mstep; mask[0] = mask[size.width-1] = WSHED; for( j = 1; j < size.width-1; j++ ) { int* m = mask + j; if( m[0] < 0 ) m[0] = 0; if( m[0] == 0 && (m[-1] > 0 || m[1] > 0 || m[-mstep] > 0 || m[mstep] > 0) ) { const uchar* ptr = img + j*3; int idx = 256, t; if( m[-1] > 0 ) c_diff( ptr, ptr - 3, idx ); if( m[1] > 0 ) { c_diff( ptr, ptr + 3, t ); idx = ws_min( idx, t ); } if( m[-mstep] > 0 ) { c_diff( ptr, ptr - istep, t ); idx = ws_min( idx, t ); } if( m[mstep] > 0 ) { c_diff( ptr, ptr + istep, t ); idx = ws_min( idx, t ); } assert( 0 <= idx && idx <= 255 ); ws_push( idx, i*mstep + j, i*istep + j*3 ); m[0] = IN_QUEUE; } } } // find the first non-empty queue for( i = 0; i < NQ; i++ ) if( q[i].first ) break; // if there is no markers, exit immediately if( i == NQ ) return; active_queue = i; img = src.data; mask = dst.ptr<int>(); // recursively fill the basins for(;;) { int mofs, iofs; int lab = 0, t; int* m; const uchar* ptr; if( q[active_queue].first == 0 ) { for( i = active_queue+1; i < NQ; i++ ) if( q[i].first ) break; if( i == NQ ) break; active_queue = i; } ws_pop( active_queue, mofs, iofs ); m = mask + mofs; ptr = img + iofs; t = m[-1]; if( t > 0 ) lab = t; t = m[1]; if( t > 0 ) { if( lab == 0 ) lab = t; else if( t != lab ) lab = WSHED; } t = m[-mstep]; if( t > 0 ) { if( lab == 0 ) lab = t; else if( t != lab ) lab = WSHED; } t = m[mstep]; if( t > 0 ) { if( lab == 0 ) lab = t; else if( t != lab ) lab = WSHED; } assert( lab != 0 ); m[0] = lab; if( lab == WSHED ) continue; if( m[-1] == 0 ) { c_diff( ptr, ptr - 3, t ); ws_push( t, mofs - 1, iofs - 3 ); active_queue = ws_min( active_queue, t ); m[-1] = IN_QUEUE; } if( m[1] == 0 ) { c_diff( ptr, ptr + 3, t ); ws_push( t, mofs + 1, iofs + 3 ); active_queue = ws_min( active_queue, t ); m[1] = IN_QUEUE; } if( m[-mstep] == 0 ) { c_diff( ptr, ptr - istep, t ); ws_push( t, mofs - mstep, iofs - istep ); active_queue = ws_min( active_queue, t ); m[-mstep] = IN_QUEUE; } if( m[mstep] == 0 ) { c_diff( ptr, ptr + istep, t ); ws_push( t, mofs + mstep, iofs + istep ); active_queue = ws_min( active_queue, t ); m[mstep] = IN_QUEUE; } } }
void ForegroundSeperation(RGBTYPE* src,RGBTYPE* dst){ UINT8T* markers, *m; UINT32T** pt; UINT32T i,j,pos,en = 256, qt; UINT8T active_queue; UINT8T t,dr,db,dg,lab,cnt; UINT16T idx; UINT16T ha[C],he[R],right; //WSQ q[SIZE];//储存mask和图像坐标的队列 WSQ* q; #ifdef WIN32 UINT8T pRGB[SIZE * 3]; CvPoint start_pt; CvPoint end_pt; IplImage *img; #endif q = (WSQ*)malloc(sizeof(WSQ)*SIZE); markers = (UINT8T*)malloc(sizeof(UINT8T)*SIZE); for(i = 0; i != SIZE; i++)//初始化队列 {q[i].next = i; q[i].flag = 0;q[i].en = 0; q[i].pos = 0;} //这里改marker for( i = 0; i != R; i++) for( j = 0; j != C; j++) { if(i == 0 || j == 0 || i == R-1 || j == C-1) markers[i*C+j] = WSHED; else if( i > R/2 && j < C/3 ) markers[i*C+j] = FGND; else if( i < R/20 || j > C/2 || (j>30)&&(i>(-(j*0.4)+660))) // markers[i*C+j] = BGND; else markers[i*C+j] = 0; } showImage_1ch(markers,"marker"); //draw a pixel-wide border of dummy "watershed" (i.e. boundary) pixels //for( j = 0; j < C; j++) //markers[j] = markers[j+(R-1)*C] = WSHED; // initial phase: put all the neighbor pixels of each marker to the ordered queue - // determine the initial boundaries of the basins for( i = 1; i < R-1; i++) { //markers[i*C] = markers[i*C+C-1] = WSHED; for( j = 1; j < C-1; j++) { m = markers + i*C+j; if( m[0] > 2 ) m[0] = 0; if( m[0] == 0 && ( (m[-1] < 3 && m[-1] > 0) || (m[1] < 3 && m[1] > 0) || (m[-C] < 3 && m[-C] > 0) || (m[C] < 3 && m[C] > 0) )) { pos = i*C + j; idx = 256; if( m[-1] < 3 && m[-1] > 0 ) c_diff(src[pos],src[pos-1],idx); if( m[1] < 3 && m[1] > 0 ) { c_diff(src[pos],src[pos+1],t); idx = ws_min(idx,t); } if( m[-C] < 3 && m[-C] > 0 ) { c_diff(src[pos],src[pos-C],t); idx = ws_min(idx,t); } if( m[C] < 3 && m[C] > 0 ) { c_diff(src[pos],src[pos+C],t); idx = ws_min(idx,t); } ws_push(idx, pos); m[0] = IN_QUEUE; } } } // find the first non-empty queue for( i = 0; i < NQ; i++) if(q[i].flag) break; if( i == NQ ) return; active_queue = i; m = markers; while(1) { lab = 0; if(!q[active_queue].flag) { for( i = active_queue+1; i<NQ; i++) if( q[i].flag) break; if( i == NQ) break; active_queue = i; } ws_pop(active_queue,pos); m = markers + pos; t = m[-1]; if( t < 3 && t > 0 ) lab = t; t = m[1]; if( t < 3 && t > 0 ) { if( lab == 0 ) lab = t; else if( t != lab ) lab = WSHED; } t = m[-C]; if( t < 3 && t > 0 ) { if( lab == 0 ) lab = t; else if( t != lab ) lab = WSHED; } t = m[C]; if( t < 3 && t > 0 ) { if( lab == 0 ) lab = t; else if( t != lab ) lab = WSHED; } if(lab == 0) lab = 0; m[0] = lab; if( !(lab == FGND || lab == BGND)) continue; if( m[-1] == 0 ) { c_diff( src[pos], src[pos-1],t); pos--; ws_push(t,pos); pos++; active_queue = ws_min(active_queue,t); m[-1] = IN_QUEUE; } if( m[1] == 0 ) { c_diff( src[pos], src[pos+1],t); pos++; ws_push(t,pos); pos--; active_queue = ws_min(active_queue,t); m[1] = IN_QUEUE; } if( m[-C] == 0 ) { c_diff( src[pos], src[pos-C],t); pos-=C; ws_push(t,pos); pos+=C; active_queue = ws_min(active_queue,t); m[-C] = IN_QUEUE; } if( m[C] == 0 ) { c_diff( src[pos], src[pos+C],t); pos+=C; ws_push(t,pos); pos-=C; active_queue = ws_min(active_queue,t); m[C] = IN_QUEUE; } } for( i = 0; i < R; i++) for( j = 0; j < C; j++) { pos = i*C+j; if(markers[pos] == BGND) { dst[pos].r = 0; dst[pos].g = 0; dst[pos].b = 0; } else if(markers[pos] == WSHED) { dst[pos].r = 255; dst[pos].g = 0; dst[pos].b = 0; } else dst[pos] = src[pos]; } for( i = 0; i < C; i++ ) ha[i] = 0; for( i = 0; i < R; i++ ) he[i] = 0; for( i = 1; i < C-1; i++) for( j = 1; j < R-1; j++ ) if(markers[j*C+i] == WSHED) {ha[i]++;he[j]++;} //for( i = 0; i < C; i++) printf("%d ",ha[i]); //printf("\n"); //for( i = 0; i < R; i++) printf("%d ",he[i]); //现在检测右边界! for( i = 1; i < C-1; i++) { if(ha[i]<10) { cnt = 0; continue; } else{ if(++cnt > 3) {right = i-2;break;} } } #ifdef WIN32 start_pt = cvPoint(right,1); end_pt = cvPoint(right,R-1); memset(pRGB, 0, SIZE * 3); //初始化 for (i = 0; i < R; i++) //int不够,必须二重循环 { for (j = 0; j < C; j++) { pRGB[i*C * 3 + j * 3] = dst[i*C + j].b; pRGB[i*C * 3 + j * 3 + 1] = dst[i*C + j].g; pRGB[i*C * 3 + j * 3 + 2] = dst[i*C + j].r; } } img = cvCreateImageHeader(cvSize(C,R),IPL_DEPTH_8U,3); cvSetData(img,pRGB,3*C); cvLine(img, start_pt, end_pt, CV_RGB(0, 0, 255), 1, CV_AA, 0); #endif //现在检测上边界!! for( i = 0; he[i] == 0;i++); up_st.y = i; up_st.x = 1; cnt = 0; for( i = up_st.y; i < R-1; i++) { if(he[i] != 1) {cnt = 0; continue;} else { cnt++; if( cnt > 3 ) break; } } up_en.y = i-2; for( i = 1; i < C-1; i++ ) if( markers[up_en.y*C+i] == WSHED) break; up_en.x = i; #ifdef WIN32 start_pt = cvPoint(1,up_st.y); end_pt = cvPoint(i,up_en.y); cvLine(img, start_pt, end_pt, CV_RGB(0, 0, 255), 1, CV_AA, 0); cvNamedWindow("hahaha", 0); cvShowImage("hahaha", img); cvWaitKey(0); #endif //不准的下边界 /* for( i = up_en.y; i < R-1; i++){ if(he[i] == 1) {cnt = 0; continue;} else{ cnt++; if(cnt == 3) break; } } down_st.y = i - 3; for( i = 1; i < C-1; i++) if(markers[i+down_st.y*C] == WSHED) break; down_st.x = i; for( i = down_st.y; he[i]; i++); down_en.y = i-1; for( i = 1; i < C-1; i++) if(markers[i+down_en.y*C] == WSHED) break; down_en.x = i; #ifdef WIN32 start_pt = cvPoint(down_st.x,down_st.y); end_pt = cvPoint(down_en.x,down_en.y); printf("%d %d %d %d",down_st.x,down_st.y,down_en.x,down_en.y); cvLine(img, start_pt, end_pt, CV_RGB(0, 0, 255), 1, CV_AA, 0); cvNamedWindow("hahaha", 0); cvShowImage("hahaha", img); cvWaitKey(0); #endif*/ free(markers); free(q); }