欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

裁剪原图像,得到ROI区域的矩形图像 (findContours()寻找轮廓,图像裁剪) OpenCV

程序员文章站 2022-03-31 23:05:28
...

我知道之前用直方图方差找最佳曝光值的算法为什么有问题了。。。
因为我新增了ROI区域裁剪,是基于轮廓提取找到ROI区域的。而我在测试的时候,黑色背景板不够大,实际拍摄的图片最外面的轮廓其实是黑色背景板的,没有成功把ROI区域裁剪出来。

本博文的代码,我用自己画的图片,能够得到正确的裁剪后的ROI图片。而用测试时相机拍摄的图片,得到的裁剪结果却与原图像几乎一模一样。

当然,裁剪后的图片中仍含有一小部分无用的背景区域。用裁剪后的图片做针对ROI区域的图像处理时,还是存在不可避免的误差。


下面给出裁剪图像ROI区域的代码:

#include <iostream>
#include <cvInclude.h>

using namespace std;

int main(void)
{
    //读入源图像
    Mat inImg = imread("F:/test.png", 0);
    imshow("input image", inImg);
    Mat inImgTemp = inImg.clone();//不要直接在源图像上进行操作


    //寻找轮廓(我们需要找到最外层轮廓)
    std::vector<std::vector<Point>> contours; //向量内 每个元素保存了 一组由连续的Point点构成的点集的向量,每一组Point点集就是一个轮廓。
    std::vector<Vec4i> hierarchy;//图的拓扑结构 第i个轮廓的后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号。
    findContours(inImgTemp, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE, Point()); //Point偏移量,所有的轮廓信息相对于原始图像对应点的偏移量


    //获取(第1个)外接矩形的4个顶点坐标 
    RotatedRect rectPoint = minAreaRect(contours[0]);
    Point2f fourPoint[4];//定义一个存储以上4个点的坐标的变量 
    rectPoint.points(fourPoint);//将rectPoint变量中存储的坐标值 放到fourPoint的数组中
    int minX = fourPoint[0].x;
    int minY = fourPoint[0].y;
    int maxX = fourPoint[0].x;
    int maxY = fourPoint[0].y;


    //输出ROI矩形四个点的坐标和并找到X,Y坐标的最大/最小值,即确定了矩形ROI区域 
    for (int i = 0; i < contours.size(); i++)//遍历每一个轮廓
    {
        //获取(第i+1个)外接矩形的4个顶点坐标 
        RotatedRect rectPoint = minAreaRect(contours[i]);
        Point2f fourPoint[4];//定义一个存储以上4个点的坐标的变量 
        rectPoint.points(fourPoint);//将rectPoint变量中存储的坐标值 放到fourPoint的数组中

        for (int j = 0; j < 4; j++)
        {
            if (fourPoint[j].x < minX)
            {
                minX = fourPoint[j].x;
            }
            if (fourPoint[j].x > maxX)
            {
                maxX = fourPoint[j].x;
            }
            if (fourPoint[j].y < minY)
            {
                minY = fourPoint[j].y;
            }
            if (fourPoint[j].y > maxY)
            {
                maxY = fourPoint[j].y;
            }
        }
    }
    int width = maxX - minX;
    int height = maxY - minY;
    std::cout << "ROI区域在源图像的左上角坐标为: " << "minX = " << minX << " , " << "minY = " << minY << std::endl;
    std::cout << "ROI区域的宽度和高度为: " << "width = " << width << " , " << "height =" << height << std::endl;


    //对源图像ROI区域进行裁剪
    Mat roiImg = inImg(Rect(minX, minY, width, height));//提取的关键就是Rect(minX, minY, width, height),其中minX, minY表示感兴趣区域的左上角位置,后面的width, height表示感兴趣部分的宽度和高度
    imshow("裁剪后的ROI图片", roiImg);


    waitKey(0);
    return 0;
}

运行结果:
裁剪原图像,得到ROI区域的矩形图像 (findContours()寻找轮廓,图像裁剪) OpenCV
裁剪原图像,得到ROI区域的矩形图像 (findContours()寻找轮廓,图像裁剪) OpenCV
裁剪原图像,得到ROI区域的矩形图像 (findContours()寻找轮廓,图像裁剪) OpenCV