首页 文章

OpenCV中的鲁棒图像分割

提问于
浏览
2

我正在尝试编写一个OpenCV程序,为其他人计算鱼卵 . 它目前需要上传图像,标准化,模糊,阈值,扩张,距离变换,阈值,然后找到轮廓(如典型的分水岭教程) .

我遇到的问题是光照条件可能会有很大差异,所以即使使用我的自适应阈值,算法的准确性也会发生很大变化 . 如果图像上有渐变亮度,那么它似乎特别差 . 有时物体在背景下非常明亮,有时它们的光度几乎相同 . 在不同的光照条件下找到物体有什么特别有效的方法吗?

示例图片:
img

gif

2 回答

  • 2

    因为大于100像素的任何东西都与图像无关,所以我会构建一个傅立叶带通滤波器来移除这些结构 .

    这是我使用的一个实现,基于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

    计算图像的alpha和beta值image = cv :: imread(“F:\ Dilated.jpg”); int x,y; int a = 0; //在循环中使用的变量int count = 0; //要在循环中使用的变量

    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 );
               }
           }
      }
    

相关问题