【问题标题】:Collecting pixel values in a line drawn using mouse在使用鼠标绘制的线条中收集像素值
【发布时间】:2014-08-20 13:42:00
【问题描述】:

我有一个图像(24 位 bmp),如下所示:

用户使用鼠标绘制一条线(此处以红色显示)。这条线可以是任何角度的任何地方。然后他单击鼠标右键或鼠标左键,图像的像素值将被存储在一个文件中,并显示在控制台上。

我使用setMouseCallback() 来显示鼠标的位置(如下所示)。但是我需要更多帮助来理解一种优雅的方式来查找和存储跨行的像素值。请帮忙!

void CallBackFunc(int event, int x, int y, int flags, void* userdata)
{
     if  ( event == EVENT_LBUTTONDOWN )
     {
          cout << "Left button of the mouse is clicked - position (" << x << ", " << y << ")" << endl;
     }
     else if  ( event == EVENT_RBUTTONDOWN )
     {
          cout << "Right button of the mouse is clicked - position (" << x << ", " << y << ")" << endl;
     }

     else if ( event == EVENT_MOUSEMOVE )
     {
          cout << "Mouse move over the window - position (" << x << ", " << y << ")" << endl;

     }
}

int main(int argc, char** argv)
{

     Mat img = imread("C:\\Users\\Acme\\Desktop\\image-processing\\2.bmp");
     namedWindow(" Window", 1);
     setMouseCallback(" Window", CallBackFunc, NULL);
     imshow(" Window", img);
     waitKey(0);
     return 0;

}

【问题讨论】:

  • 那么有什么问题,比如用直线方程计算直线经过的像素?
  • 你不能用线条作为输入图像的掩码吗?
  • 我会按照 berak 的建议使用行迭代器。使用掩码还没有给出任何命令,我猜构造线迭代将与绘制线一样复杂(如果两种算法都使用 bresenham 线算法)。
  • @Micka 正在尝试使用迭代器,但我遇到了错误Trying to understand the usage of Lineiterator

标签: c++ c opencv image-processing


【解决方案1】:

具体细节取决于您的程序,但是一旦单击两个点就会填充值。之后做什么由你自己决定。

cv::Point g_points[2];
int g_pointIndex;
std::vector<cv::Vec3b> values;
bool g_allGood = false;

void onMouse(int e, int x, int y, int d, void* ud)
{
    if (e != CV_EVENT_LBUTTONDOWN || g_pointIndex >= 2)
        return;

    g_points[g_pointIndex++] = cv::Point(x, y);
}

void main()
{
    // load image as greyscale
    Mat img = imread("C:\\temp\\2.png", CV_8UC1);
    namedWindow("img", 1);

    setMouseCallback("img", onMouse);

    while (1)
    {
        // all points collected
        if (g_pointIndex == 2 && !g_allGood)
        {
            /*
            to save processing, i suggest you remove the mouse callback once all points
            are collected. do this with: setMouseCallback("img", NULL,NULL);
            */

            // create line iterator, and add pixel values to values vector
            cv::LineIterator it(img, g_points[0], g_points[1]);

            for (int i = 0; i < it.count; i++, ++it)
                values.push_back((Vec3b)*it);

            // you now have all pixel values in values;
            g_allGood = true;
        }

        imshow("img", img);
        waitKey(100);
    }

}

【讨论】:

  • 我尝试打印 values 中的值:cout
  • 我已经编辑了代码。 values 填充了值并且肯定不为空。
  • 感谢您的编辑。实际上现在我得到运行时错误,但没有编译错误。我调试了它,当调用 setMouseCallback() 时它给出了未处理的异常。
  • 有什么例外?查看控制台窗口了解更多详情
【解决方案2】:

通过变形将线条提取为 1 x (linelength) 或 (linelength) x 1,垂直或水平的垫子。然后您可以轻松读取或跨像素值读取。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-21
    • 2012-12-14
    相关资源
    最近更新 更多