自由格式图像选择(最好用c ++)

时间:2011-11-19 06:16:18

标签: c++ image image-processing opencv

我是图像处理的新手。我注意到你可以在像opencv这样的图像处理库中指定rectangular region of interest和其他像circles等。像ms-paint这样的基本绘图程序包含了自由格式选择,但我似乎找不到关于如何在opencv或其他图像处理库中进行自由格式图像选择的功能或教程。关于如何实现这一点的任何想法? PS:我的首选语言是c / c ++。 enter image description here

2 个答案:

答案 0 :(得分:3)

你可以尝试一件事:

如果选择可以表示为2d向量序列,则可以将其视为多边形。分配一个新的1通道图像作为你的面具并用0填充。然后使用

void cvFillPoly(CvArr* img, CvPoint** pts, int* npts, int contours, CvScalar color, int lineType=8, int shift=0)

记录在

http://opencv.willowgarage.com/documentation/drawing_functions.html

在蒙版图像上绘制非零区域,以表示图像的选定部分。

答案 1 :(得分:1)

我写了一个演示来显示图像并在鼠标移动时画出小绿点,见下文。

你需要知道 OpenCV不是为这种类型的交互而设计的,所以性能是个问题(而且很糟糕)!你会明白我的意思。

#include <stdio.h>    
#include <cv.h>
#include <highgui.h>

// mouse callback    
void on_mouse(int event, int x, int y, int flags, void* param)
{
    // Remove comment below to paint only when left mouse button is pressed
    //if (event == CV_EVENT_LBUTTONDOWN)
    {
        //fprintf(stderr, "Painting at %dx%d\n", x, y);
        IplImage* img = (IplImage*)param;

        cvCircle(img, cvPoint(x,y), 1, CV_RGB(0, 255, 0), -1, CV_AA, 0);
            cvShowImage("cvPaint", img);
    }
}


int main(int argc, char* argv[])
{
    if (argc < 2)
    {
        fprintf( stderr, "Usage: %s <img>\n", argv[0]);
        return -1;
    }

    IplImage* frame = NULL; 
    frame = cvLoadImage(argv[1], CV_LOAD_IMAGE_UNCHANGED);
    if (!frame)
    {
        fprintf( stderr, "Failed: Couldn't load file %s\n", argv[1]);
        return -1;
    }

    cvNamedWindow("cvPaint", CV_WINDOW_AUTOSIZE);
    cvShowImage("cvPaint", frame);

    cvSetMouseCallback("cvPaint", &on_mouse, frame);
    while (1)
    {
        // Keep looping to prevent the app from exiting, 
        // so the mouse callback can be called by OpenCV and do some painting

        char key = cvWaitKey(10);
        if (key  == 113 || key == 27) // q was pressed on the keyboard
            break;
    }

    cvReleaseImage(&frame);
    cvDestroyWindow("cvPaint");

    return 0;
}

我的建议是你使用其他窗口系统进行此类任务,其中性能更好。例如,看看 Qt 。但是,如果您愿意,也可以使用 win32 X 等原生方式进行平台。

对于问题的其他部分,如何裁剪用户选择,我建议您查看以下代码:OpenCV resizing and cropping image according to pixel value

此外,在用户绘制图像时记录鼠标坐标比分析绘制绿点的图像更加实用。然后分析这些坐标并从中检索最小的矩形区域。这就是这个逻辑变得有用的时候了:

CvScalar s;        
for (x=0; x<width-1; x++)
{
    for(y=0; y<height-1; y++)
    {
        s = cvGet2D(binImage, y, x);
        if (s.val[0] == 1)
        {
            minX = min(minX, x);
            minY = min(minY, y);
            maxX = max(maxX, x);
            maxY = max(maxY, y);
        }   
    }
}

cvSetImageROI(binImage, cvRect(minX, minY, maxX-minX, maxY-minY));

在这种特定情况下,您不会迭代图像来查找用户在该问题中所做的特定像素,而是迭代鼠标移动过程中记录的坐标数组。