OpenCV的2.3Ç - 如何隔离内部图像对象 [英] OpenCv 2.3 C - How to isolate object inside image

查看:170
本文介绍了OpenCV的2.3Ç - 如何隔离内部图像对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样一个形象:

我要删除的黑色行列数轮数。
所以我希望的结果是:

i want to remove the black rows and cols round the number. So i want that the result is:

我尝试这个办法:

void findX(IplImage* imgSrc,int* min, int* max){
    int i;
    int minFound=0;
    CvMat data;
    CvScalar maxVal=cvRealScalar(imgSrc->width * 255);
    CvScalar val=cvRealScalar(0);
    //For each col sum, if sum < width*255 then we find the min
    //then continue to end to search the max, if sum< width*255 then is new max
    for (i=0; i< imgSrc->width; i++){
        cvGetCol(imgSrc, &data, i);
        val= cvSum(&data);
        if(val.val[0] < maxVal.val[0]){
            *max= i;
            if(!minFound){
                *min= i;
                minFound= 1;
            }
        }
    }
}

void findY(IplImage* imgSrc,int* min, int* max){
    int i;
    int minFound=0;
    CvMat data;
    CvScalar maxVal=cvRealScalar(imgSrc->width * 255);
    CvScalar val=cvRealScalar(0);
    //For each col sum, if sum < width*255 then we find the min
    //then continue to end to search the max, if sum< width*255 then is new max
    for (i=0; i< imgSrc->height; i++){
        cvGetRow(imgSrc, &data, i);
        val= cvSum(&data);
        if(val.val[0] < maxVal.val[0]){
            *max=i;
            if(!minFound){
                *min= i;
                minFound= 1;
            }
        }
    }
}
CvRect findBB(IplImage* imgSrc){
    CvRect aux;
    int xmin, xmax, ymin, ymax;
    xmin=xmax=ymin=ymax=0;

    findX(imgSrc, &xmin, &xmax);
    findY(imgSrc, &ymin, &ymax);

    aux=cvRect(xmin, ymin, xmax-xmin, ymax-ymin);

    //printf("BB: %d,%d - %d,%d\n", aux.x, aux.y, aux.width, aux.height);

    return aux;

}

所以我用:

IplImage *my_image = cvLoad....
CvRect bb = findBB(my_image);
IplImage *new_image = cvCreateImage(cvSize(bb.width,bb.height), my_image->depth, 1);
cvShowImage("test",new_image);

这是行不通的好,因为我尝试检查,如果在新的图像有黑行列的,他们是present。我能做什么?有人可以帮我吗? (对不起,我的英语!)

it doesn't work good, cause i try to check if in new image there are black rows or cols and they are present. what can i do? can someone help me? (sorry for my english!)

推荐答案

要做到这一点是简单地执行的边框技术检测数字,

One way to do it is to simply execute the bounding box technique to detect the digit, as illustrated by the image below:

由于你的形象已经处理的边框技术,我用的是简单了很多。

Since your image is already processed the bounding box technique I use is a lot simpler.

这过程之后,你真正需要做的是原始图像的设置ROI(感兴趣区域)由框定义的区域来实现的作物效应和隔离对象:

After that procedure, all you really need to do is set the ROI (Region of Interest) of the original image to the area defined by the box to achieve the crop effect and isolate the object:

注意,结果图像中有一个额外的行/边界不属于白色像素列。那么,他们是不是黑色两种。那是因为我没有任何执行阈值法二值化图像为黑白。低于code展示在图像的灰度版本正在执行的边界框的技术。

Notice that in the resulting image there is one extra row/column of pixels in the border that are not white. Well, they are not black either. That's because I didn't performed any threshold method to binarize the image to black and white. The code below demonstrates the bounding box technique being executed on a grayscale version of the image.

这是pretty大部分的路线图,以实现你想要的。教育目的,我的共享code我用的OpenCV的C ++接口写道。我敢肯定,你有能力将其转换为C接口的。

This is pretty much the roadmap to achieve what you want. For educational purposes I'm sharing the code I wrote using the C++ interface of OpenCV. I'm sure you are capable of converting it to the C interface.

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

#include <vector>


int main(int argc, char* argv[])
{
    cv::Mat img = cv::imread(argv[1]);

    // Convert RGB Mat to GRAY
    cv::Mat gray;
    cv::cvtColor(img, gray, CV_BGR2GRAY);

    // Store the set of points in the image before assembling the bounding box
    std::vector<cv::Point> points;
    cv::Mat_<uchar>::iterator it = gray.begin<uchar>();
    cv::Mat_<uchar>::iterator end = gray.end<uchar>();
    for (; it != end; ++it)
    {
        if (*it) points.push_back(it.pos());
    }

    // Compute minimal bounding box
    cv::RotatedRect box = cv::minAreaRect(cv::Mat(points));

// Draw bounding box in the original image (debug purposes)
//cv::Point2f vertices[4];
//box.points(vertices);
//for (int i = 0; i < 4; ++i)
//{
        //cv::line(img, vertices[i], vertices[(i + 1) % 4], cv::Scalar(0, 255, 0), 1, CV_AA);
//}
//cv::imshow("box", img);
//cv::imwrite("box.png", img);

    // Set Region of Interest to the area defined by the box
    cv::Rect roi;
    roi.x = box.center.x - (box.size.width / 2);
    roi.y = box.center.y - (box.size.height / 2);
    roi.width = box.size.width;
    roi.height = box.size.height;

    // Crop the original image to the defined ROI
    cv::Mat crop = img(roi);
    cv::imshow("crop", crop);

    cv::imwrite("cropped.png", crop);
    cvWaitKey(0);

    return 0;
}

这篇关于OpenCV的2.3Ç - 如何隔离内部图像对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆