用roi c ++滑动窗口

时间:2016-04-12 08:55:21

标签: c++ indexing

我对以下for循环的索引问题很少。只是我用roi扫描图像但我无法扫描整个图像。我在最后一行和列中留下了一些非扫描区域。有什么建议吗? 对不起简单的问题。

`

// Sliding Window for scaning the image
for (int rowIndex = 0; rowIndex <= lBPIIImage2.rows - roih; rowIndex = getNextIndex(rowIndex, lBPIIImage2.rows, roih, steprow))

{
    for (int colindex = 0; colindex <=lBPIIImage2.cols - roiw; colindex = getNextIndex(colindex, lBPIIImage2.cols, roiw, stepcol))

    {
        searchRect = cvRect(colindex, rowIndex, roiw, roih);
        frameSearchRect = lBPIIImage2(searchRect);
        LoopDummy = frameSearchRect.clone();
        rectangle(frame, searchRect, CV_RGB(255, 0, 0), 1, 8, 0);
        //normalize(LoopDummy, LoopDummy, 0, 255, NORM_MINMAX, CV_8UC1);
        //imshow("Track", LoopDummy);
        //waitKey(30);
        images.push_back(LoopDummy);
        Coordinate.push_back(make_pair(rowIndex, colindex));
    }

}

2 个答案:

答案 0 :(得分:0)

而不是这个

for (int rowindex = 0; rowindex <= frameWidth - roiw; rowindex += StepRow) 

尝试这样的事情

for (int rowIndex = 0; rowIndex < frameWidth - roiw;
    rowIndex = getNextIndex(rowIndex, frameWidth, roiw, StepRow))

其中函数getNextIndex是这样的:

int getNextIndex(int currentIndex, int frameSize, int roi, int step)
{
    int temp = min(currentIndex + step, frameSize - roi - 1);
    return currentIndex != temp ? temp : frameSize;
}

请注意,我在循环的条件部分将<=替换为<。改变那一点对我来说是有道理的。在我的评论中,索引值应为0,5,6,而不是0,5,7。如果确实应该<=,那么只需删除上面的- 1部分。

答案 1 :(得分:0)

Dialecticusproblem covered,但我想稍微扩展一下。正如您所注意到的那样,问题会影响行和列,但我只会谈论宽度,因为高度处理是类似的。

循环迭代的数组或范围的某些部分,尤其是最后的部分,是循环的条件和/或增量不覆盖整个数组/范围并需要调整的典型症状。在您的情况下,要扫描整个图像宽度,您需要frameWidth - roiw确切的StepRow个数,即(frameWidth - roiw) % StepRow == 0。我强烈怀疑你的情况并非如此。

例如,如果您的图片宽度为14像素,并且您感兴趣的区域宽度为8,那么您的步骤would be 4 pixels(我假设您的意思是roiw * 0.5),则会发生这种情况: incorrect step iteration

迭代#3将无法通过rowindex <= frameWidth - roiw测试并退出循环而不扫描最后2个像素。

我看到三个选项,每个选项都有其缺点:

免责声明:以下所有代码均未经过测试,可能包含拼写错误和逻辑错误。请相应地进行测试和调整。

  1. 更改最后一个区域的偏移量,使其适合图像的末尾。在这种情况下,最后rowindex增量不会是StepRow,而是最后一个扫描区域末尾与图像末尾之间的像素数。缺点是最后两个区域可能比它们之前的区域重叠 - 在我们的例子中,区域1将覆盖像素0:7,区域2 - 4:11和区域3 - 6:13。

    为此,您可以修改循环增量以检查这是否是最后一次迭代(请考虑如何将其写得更漂亮,我只是使用三元运算符来使更改更小):

    for (int rowindex = 0;
         /* Note that a region of (roiw) pixels ending at (frameWidth - 1) should start
            at (frameWidth - roiw), so the <= operator should be correct. To verify that,
            check the single-region case where rowindex == 0 and frameWidth == roiw */
         rowindex <= frameWidth - roiw;
         rowindex += ((rowindex + roiw + StepRow <= frameWidth) ?
                     StepRow :
                     (frameWidth - (rowindex + roiw))))
    
  2. 将最后一个区域的大小固定到图像的末尾。缺点是你的最后一个区域比之前的区域小 - 在我们的例子中,区域1和2的大小为8,而区域3的大小为6像素。

    为此,您可以在构建cvRect时进行检查,看是否需要更小。您还应该以某种方式更改循环条件,以便在这种情况下实际输入它:

    /* (StepRow - 1) should make sure that enter the loop is entered when the
       last unscanned region has a width between 1 and stepRow, inclusive */
    for (int rowindex = 0; rowindex <= frameWidth - roiw + (StepRow - 1); rowindex += StepRow) 
    /* ... column loop ... */
      {
        if (rowindex > frameWidth - roiw)
        {
          roiw = frameWidth - rowindex;
        }
        searchRect = cvRect(rowindex, colindex, roiw, roih)
    
  3. 使用变化步骤,使您的区域宽度相等,并尽可能相等地重叠。在我们的例子中,三个区域将重叠相同,位于像素0:7,3:11和6:14,但显然在大多数情况下都不会这样。

    为此,您可以计算您希望对当前步骤执行的迭代次数,然后将该数字除以帧和ROI宽度之间的差异,这将为您提供分数步骤。由于像素偏移是一个整数,要构造cvRect,您需要一个整数值。我建议保留并递增rowindex并将步长作为分数并在cvRect构造函数中使用之前转换为int - 这样,您的索引将尽可能均匀地移动。

    请注意,当float值非常接近int时,我使用了epsilon值(希望)避免在float-to-int转换中舍入错误。有关该技术的示例和说明,请参阅this blog post and comments。但是,请记住,代码未经过测试,可能仍存在舍入错误,尤其是在int值很大的情况下!

    /* To see how these calculations work out, experiment with
       roiw == 8, StepRow == 4 and frameWidth == 14, 15, 16, 17 */
    /* N.B.: Does not cover the case when frameWidth < roiw! */
    int stepRowCount = (frameWidth - roiw + (StepRow - 1)) / StepRow + 1;
    float step = ((float)(frameWidth - roiw)) / (stepRowCount - 1);
    float eps = 0.005;
    
    for (float rowindex = 0.0; (int)(rowindex + eps) <= frameWidth - roiw; rowindex += StepRow) 
    /* ... column loop ... */
      {    searchRect = cvRect((int)(rowindex + eps), colindex, roiw, roih);
    
  4. PS:迭代图像宽度的索引不应该被称为 colindex ,反之亦然,因为在1920x1080图像中,你有1920列和1080行(因此像 1080p < / em>的)?