在第二次运行时打开CV image.at <vec3b>(b,a)while循环中的函数错误

时间:2015-10-27 23:40:37

标签: c++ opencv

我的代码使用OPENCV进行图像处理,我想随机创建一个白色点的功能集。运行内部WHILE LOOP SECOND TIME 时,程序会导致断言失败错误。我评论并测试了该程序,以确切找到问题所在。我发现了 image.at(b,a)部分代码的问题。它无法第二次运行。虽然第一次运行得非常好 如果我运行具有常量值而不是变量b的代码,则在内部while循环中运行,或者运行(j,j)变量。我用fout打印一些调试语句。我还附加了.txt文件输出,以帮助您了解正在发生的事情。

从TXT文件开始输出

启动while循环

在while循环中

在while循环之外的

[255,255,255] 404 1173启动while循环

在while循环中

TXT文件输出结束

很奇怪。请帮我解决这个问题!! 我正在粘贴我的代码:

int main() {
    int i = 0;
    int a;
    ofstream fout("test.txt");
    int b;
    int j = 0;
    cv::Mat img;
    cv::Scalar* scalar_low;
    cv::Scalar* scalar_up;
    cv::Mat newimg;
    cv::Mat img2;
    stringstream ss;
    string s;
    scalar_low = new cv::Scalar(0, 30, 60);
    scalar_up = new cv::Scalar(20, 150, 255);
    int imgwidth;
    int imgheight;
    srand(112);
    while (j <= 45)
    {
    s="imagedata\\test"+ to_string(j);    
    s+=".jpg";
    img=imread(s);    
    cvtColor(img, img2, CV_BGR2HSV, 0);
    inRange(img2, *scalar_low, *scalar_up, newimg);            
    s="imagedata\\result"+ to_string(j);
    s+=".jpg";
    imwrite(s, newimg);
    imgwidth = newimg.cols;
    imgheight = newimg.rows;
    i = 0;
    while (i <= 499)
    {
        a = 0;
        b = 0;
               fout << "start of while loop \n";

            while ((newimg.at<Vec3b>(b,a) == Vec3b(0,0,0)))    
            {
                fout << "inside the while loop \n"
                a = rand() % imgwidth;
                b = rand() % imgheight;

            }
            fout << "outside the while loop \n"; 
            fout << a;
            fout << " ";
            fout << b;
            fout << " ";
            i++;

        }

        j++;
        fout << "\n";

    }


}

2 个答案:

答案 0 :(得分:1)

  

我正在尝试构建一个从过滤后的图像中为白色的随机要素集。这需要我随机生成点并检查它们是否为白色

您无需在正确的图像范围内生成随机点,并检查原始图像中的像素是否为白色。

你可以:

  • 使用findNonZero
  • 获取蒙版中的所有白色像素
  • 使用std::random_shuffle
  • 随机随机播放这些点
  • 保留第一个N洗牌点

蒙面图片:

enter image description here

掩码中的随机抽样N白点:

enter image description here

代码:

#include <opencv2\opencv.hpp>
#include <vector>
#include <algorithm>
using namespace cv;
using namespace std;

int main()
{
    Mat3b img = imread("path_to_image");

    Mat3b hsv;
    cvtColor(img, hsv, COLOR_BGR2HSV);

    Mat1b mask;
    inRange(hsv, Scalar(0, 30, 60), Scalar(20, 150, 255), mask);

    // Get all white points in mask
    vector<Point> pts;
    findNonZero(mask, pts);

    int N = 1000; // number of random points to keep
    N = min(N, int(pts.size())); // not more than the actual white pixels

    // Random shuffle of white points
    random_shuffle(pts.begin(), pts.end());

    // Random subset of N white points in mask
    vector<Point> my_random_points(pts.begin(), pts.begin() + N);

    // Create a black image
    Mat1b random_in_mask(mask.rows, mask.cols, uchar(0));

    // Set selected random points to white
    for (const Point& pt : my_random_points)
    {
        random_in_mask(pt) = uchar(255);
    }

    imshow("Mask", mask);
    imshow("Random in Mask", random_in_mask);

    waitKey();

    return 0;
}

答案 1 :(得分:0)

编辑: InRange将newimg类型ucharCV_8U留下newimg.at<uchar>(a,b) == (uchar) 0 ,因此请将条件更改为:

row

将解决问题。根据以下评论更新了我的答案。

根据thisat<>(i,j)是尺寸0,即宽度。在i中,j沿着维度0 rand()沿着1.您的图像可能是矩形的,因此第二对a - s结果导致错误{{ 1}},b - :S

编辑:在您的代码中,您有

while ((newimg.at<Vec3b>(b,a) == Vec3b(0,0,0)))    
{
     fout << "inside the while loop \n"
     a = rand() % imgwidth;
     b = rand() % imgheight;
}

将此更改为

while ((newimg.at<Vec3b>(b,a) == Vec3b(0,0,0)))    
{
     fout << "inside the while loop \n"
     a = rand() % imgheight;
     b = rand() % imgwidth;
}

while ((newimg.at<Vec3b>(a,b) == Vec3b(0,0,0)))    
{
     fout << "inside the while loop \n"
     a = rand() % imgwidth;
     b = rand() % imgheight;
}

我说这应该有用,而不是它会。

编辑#2:解释

你有一张看起来像这样的照片:

-----------
|         |
|         |
|         |
|         |
|         |
|         |
-----------

但是a和at&lt;&gt;(b,a)使用顺序会创建一个不同的矩形,所以:

------------------
|         |      |
|         |   2  |
|     1   |      |
|---------|-------
|         |
|         |
-----------

您的第一对随机数已生成到(1)位置,而第二对不在图像上。您没有使用srand(time(NULL));,因此每次运行时您的随机数都相同。