2014-06-18 3 views
1

다른 사람의 생선 알을 계산하는 OpenCV 프로그램을 작성하려고합니다. 현재 업로드 된 이미지를 가져 와서 표준화, 흐림, 임계 값, 확장, 거리 변환, 임계 값을 다시 찾은 다음 윤곽을 찾습니다 (일반적인 유역 튜토리얼에서와 같이).OpenCV의 강력한 이미지 세분화

조명 조건이 상당히 다를 수 있으므로 문제의 적응 임계 값을 사용하더라도 알고리즘의 정확도가 크게 달라집니다. 이미지 전체에 그래디언트 밝기가 있으면 특히 좋지 않은 것처럼 보입니다. 때로는 물체가 배경에 대해 매우 밝을 때도 있고 다른 때는 거의 같은 밝기입니다. 다양한 조명 조건에서 물체를 발견하는 특히 효과적인 방법이 있습니까?

샘플 이미지 : 화상 화상 :: = CV imread의 img gif

+0

http://en.wikipedia.org/wiki/Histogram_equalization을 패치 수준은 (예 : 5 × 5에서 이미지를 분할 = 25 개의 패치로 다른 조명이있을 경우 다른 통계를 예측할 수 있습니다.) – Pavel

+0

달걀이없는 다른 달걀과 지역을 겹쳐서 패치하는 경우 결과가 좋을 것이라고 생각합니다. 큰 블록 크기의 adaptiveThreshold()를 사용하고 그라디언트 조명에 도움이되었지만 항상 외부 객체를 감지했습니다. – vityav

답변

1

에 사용되는, 나는이 구조를 제거하는 푸리에 대역 통과 필터를 구성합니다.

다음은 ImageJ에 기반한 구현입니다. 이 구현 예에서, 입력 이미지는 에지 아티팩트를 감소시키기 위해 미러 패딩된다. 여기 사용

static void GenerateBandFilter(thrust::host_vector<float>& filter, const BandPassSettings& band, const FrameSize& frame) 
    { 
     //From https://imagej.nih.gov/ij/plugins/fft-filter.html 
     if (band.do_band_pass == false) 
     { 
      return; 
     } 
     if (frame.width != frame.height) 
     { 
      throw std::runtime_error("Frame height and width should be the same"); 
     } 
     auto maxN = static_cast<int>(std::max(frame.width, frame.height));//todo make sure they are the same 

     auto filterLargeC = 2.0f*band.max_dx/maxN; 
     auto filterSmallC = 2.0f*band.min_dx/maxN; 
     auto scaleLargeC = filterLargeC*filterLargeC; 
     auto scaleSmallC = filterSmallC*filterSmallC; 

     auto filterLargeR = 2.0f*band.max_dy/maxN; 
     auto filterSmallR = 2.0f*band.min_dy/maxN; 
     auto scaleLargeR = filterLargeR*filterLargeR; 
     auto scaleSmallR = filterSmallR*filterSmallR; 

     // loop over rows 
     for (auto j = 1; j < maxN/2; j++) 
     { 
      auto row = j * maxN; 
      auto backrow = (maxN - j)*maxN; 
      auto rowFactLarge = exp(-(j*j) * scaleLargeR); 
      auto rowFactSmall = exp(-(j*j) * scaleSmallR); 
      // loop over columns 
      for (auto col = 1; col < maxN/2; col++) 
      { 
       auto backcol = maxN - col; 
       auto colFactLarge = exp(-(col*col) * scaleLargeC); 
       auto colFactSmall = exp(-(col*col) * scaleSmallC); 
       auto factor = (((1 - rowFactLarge*colFactLarge) * rowFactSmall*colFactSmall)); 
       filter[col + row] *= factor; 
       filter[col + backrow] *= factor; 
       filter[backcol + row] *= factor; 
       filter[backcol + backrow] *= factor; 
      } 
     } 
     auto fixy = [&](float t){return isinf(t) ? 0 : t; }; 
     auto rowmid = maxN * (maxN/2); 
     auto rowFactLarge = fixy(exp(-(maxN/2)*(maxN/2) * scaleLargeR)); 
     auto rowFactSmall = fixy(exp(-(maxN/2)*(maxN/2) *scaleSmallR)); 
     filter[maxN/2] *= ((1 - rowFactLarge) * rowFactSmall); 
     filter[rowmid] *= ((1 - rowFactLarge) * rowFactSmall); 
     filter[maxN/2 + rowmid] *= ((1 - rowFactLarge*rowFactLarge) * rowFactSmall*rowFactSmall); // 
     rowFactLarge = fixy(exp(-(maxN/2)*(maxN/2) *scaleLargeR)); 
     rowFactSmall = fixy(exp(-(maxN/2)*(maxN/2) *scaleSmallR)); 
     for (auto col = 1; col < maxN/2; col++){ 
      auto backcol = maxN - col; 
      auto colFactLarge = exp(-(col*col) * scaleLargeC); 
      auto colFactSmall = exp(-(col*col) * scaleSmallC); 
      filter[col] *= ((1 - colFactLarge) * colFactSmall); 
      filter[backcol] *= ((1 - colFactLarge) * colFactSmall); 
      filter[col + rowmid] *= ((1 - colFactLarge*rowFactLarge) * colFactSmall*rowFactSmall); 
      filter[backcol + rowmid] *= ((1 - colFactLarge*rowFactLarge) * colFactSmall*rowFactSmall); 
     } 
     // loop along column 0 and expanded_width/2 
     auto colFactLarge = fixy(exp(-(maxN/2)*(maxN/2) * scaleLargeC)); 
     auto colFactSmall = fixy(exp(-(maxN/2)*(maxN/2) * scaleSmallC)); 
     for (auto j = 1; j < maxN/2; j++) { 
      auto row = j * maxN; 
      auto backrow = (maxN - j)*maxN; 
      rowFactLarge = exp(-(j*j) * scaleLargeC); 
      rowFactSmall = exp(-(j*j) * scaleSmallC); 
      filter[row] *= ((1 - rowFactLarge) * rowFactSmall); 
      filter[backrow] *= ((1 - rowFactLarge) * rowFactSmall); 
      filter[row + maxN/2] *= ((1 - rowFactLarge*colFactLarge) * rowFactSmall*colFactSmall); 
      filter[backrow + maxN/2] *= ((1 - rowFactLarge*colFactLarge) * rowFactSmall*colFactSmall); 
     } 
     filter[0] = (band.remove_dc) ? 0 : filter[0]; 
    } 

enter image description here

당신은 내 코드 주위를 찌를 수 있습니다 https://github.com/kandel3/DPM_PhaseRetrieval

+0

비록이 경우에 도움이된다는 것을 아직 확인하지는 않았지만 (계란 내부가이 형태의 가장자리 감지에 크게 나타날 수 있음) 분명히 흥미롭고 밴드 패스 필터로 이미지 처리의 토끼 구멍을 이끌었습니다. – vityav

0

계산 알파 및 베타 값 ("F : \ Dilated.jpg"); int x, y; int a = 0; // 루프에서 사용할 변수 int count = 0; 100 픽셀보다 큰 아무것도 이미지와 관련이없는 때문에 // 변수가 루프

for(int y = 0; y < image.rows; y++) 
    { for(int x = 0; x < image.cols; x++) 
     { for(int c = 0; c < 3; c++) 
      { 
        image.at<Vec3b>(y,x)[c] = 
      saturate_cast<uchar>(alpha*( image.at<Vec3b>(y,x)[c]) + beta); 
      } 
     } 
    } 
+0

알파와 베타를 계산하는 방법은 무엇입니까? 당신이 일종의 선형 회귀 적합을하고있는 것처럼 보이지만, 당신이 맞는지 이해하지 못합니다. – vityav