7--OpenCV:图像基本操作之①截取②掩膜 操作

一、图像截取

1.什么是ROI

感兴趣区域(ROI,region of interest),就是从图像中选择的一个图像区域,这个区域是图像分许所关注的重点,通过圈定这个区域,一边进一步的处理,而且使用ROI指定想读入的目标,可以减少处理时间,增加精度。

2.Rect截取ROI

Rect::Rect(int x, int y, int width, int height);
/*******************************************************************
*           x:                  左上角x坐标
*           y:                  左上角y坐标
*           width:              宽度
*           height:              高度
*********************************************************************/
Mat roi= img(Rect(x, y, w, h));

3.Range截取ROI

        参数是按照行和列进行划分的。

                第一个range的两个参数分别是起点的row和终点的row。

                第二个range的两个参数分别是起点的col和终点的col

Range::Range(int _start, int _end) ;
/*******************************************************************
*           _start:              起点
*           _end:                终点 
*********************************************************************/
Mat roi= img(Range(x,xx),Range(y,yy));

4.selectROI截取ROI

        封装了三个操作如下

Rect selectROI(InputArray img, bool showCrosshair = true, bool fromCenter = false);
/*******************************************************************
*           img:                    原图
*           showCrosshair:          鼠标选框,是否显示十字线
*           fromCenter:             是否以起始鼠标位置为中心
*********************************************************************/
//Rect rect= selectROI(img, false, false);
//1.显示img
//2.鼠标选择区域
//3.使用“空格”或“enter”来完成当前选择并开始一个新的选择,使用“esc”终止多个ROI选择过程  
void selectROIs(const String& windowName, InputArray img,CV_OUT std::vector& boundingBoxes, bool showCrosshair = true, bool fromCenter = false);

5.综合代码

#include 
#include 
#include 
#include 
using namespace std;
using namespace cv;
class ROI
{
public:
    ROI() :img(imread("mm.jpg"))
    {
        roi["原图"] = img;
    }
    void GetRoiByRect(int x = 100, int y = 0, int w = 350, int h = 375)
    {
        roi["rect"] = img(Rect(x, y, w, h));
    }
    void GetRoiByRange() 
    {
        roi["range"] = img(Range(0, img.rows), Range(100, 100 + 350));
    }
    void GetRoiBySelectROI() 
    {
        Rect  rect = selectROI(img, false, true);
        //1.显示img
        //2.封装鼠标操作,支持手动选区
        //3.按回车或者esc退出
        roi["select"] = img(rect);
    }
    void Show() 
    {
        for (auto& v : roi) 
        {
            imshow(v.first, v.second);
        }
        waitKey(0);
    }
private:
    //封装一个插入函数,作为截取图像插入roi容器方式
    //void InsertROI(string imgName, Mat img) 
    //{
    //  //roi.insert(pair(imgName, img));
    //  roi[imgName] = img;
    //}
    Mat img;
    map roi;
};
​
int main() 
{
    ROI* proi = new ROI;
    proi->GetRoiByRange();
    proi->GetRoiByRect();
    proi->GetRoiBySelectROI();
    proi->Show();
    return 0;
}

二、图像掩膜操作

1.什么是掩膜操作

用一个矩阵和原图像作卷积操作,重新计算像素值,用数学术语讲,即我们自定义一个权重表

  • 掩模矩阵

  • 计算公式

7--OpenCV:图像基本操作之①截取②掩膜 操作_第1张图片

掩膜操作可以提高图像对比度,对比度提高可以增加图像感官度、锐化,让看起来有点模糊的图像更清晰

2.像素读写实现掩膜操作

注意:

        ①定义rows的时候,是img的rows-1--->防止越界(因为要访问next) 周围的四个像素

        ②定义cols的时候,是img的cols-1

        ③注意像素点ptr的函数的使用,获取像素数组

        ④saturate_cast防止像素值越界

7--OpenCV:图像基本操作之①截取②掩膜 操作_第2张图片

Mat mask = Mat::zeros(img.size(), img.type());
int dims = img.channels();
int rows = img.rows - 1;
int cols = (img.cols - 1) * dims;
for (int i = 1; i < rows; i++)
{
​
    uchar* pre = img.ptr(i - 1);
    uchar* cur = img.ptr(i);
    uchar* next = img.ptr(i + 1);
    uchar* output = mask.ptr(i);
    for (int j = dims; j < cols; j++) 
    {
        output[j] = saturate_cast(
        5 * pre[j] - cur[j - dims] - cur[j + dims] - pre[j]- next[j]);
    }
}

3.filter2D实现掩膜操作

需要定义一个权重矩阵:具体定义方法见下,Mat_(3,3)<<九个参数值

//定义掩膜矩阵
Mat dst;
Mat kernel = (Mat_(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
filter2D(img, dst, img.depth(), kernel);
/*******************************************************************
*           img:                    原图
*           dst:                    存储结果图
*           img.depth():            原图深度
*           kernel:                  掩膜矩阵
*********************************************************************/

4.综合代码

filter2D和自己操作像素得到的结果差不多。嫌麻烦可以直接fliter2D

#include 
#include 
#include 
#include 
using namespace std;
using namespace cv;
class Mask 
{
public:
    Mask() :img(imread("mm.jpg")) 
    {
        mask["原图"] = img;
    }
    void Mask_filter2D() 
    {
        Mat kernel = (Mat_(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
        filter2D(img, mask["filter2D"], img.depth(), kernel);
    }
    void Mask_pixel()
    {
        mask["pixel"] = Mat::zeros(img.size(), img.type());
        int dims = img.channels();
        int rows = img.rows - 1;
        int cols = (img.cols - 1) * dims;
        for (int i = 1; i < rows; i++) 
        {
            uchar* pre = img.ptr(i - 1);     //上一行
            uchar* cur = img.ptr(i);         //当前行
            uchar* next = img.ptr(i + 1);    //下一行
            uchar* output = mask["pixel"].ptr(i);
            for (int j = dims; j < cols; j++) 
            {
                output[j] = saturate_cast(5 * cur[j] - cur[j - dims] - cur[j + dims] - pre[j] - next[j]);
            }
        }
    }
    void Show() 
    {
        for (auto& v : mask) 
        {
            imshow(v.first, v.second);
        }
        waitKey(0);
    }
private:
    Mat img;
    map mask;
};
int main() 
{
    Mask* pmask = new Mask;
    pmask->Mask_pixel();
    pmask->Mask_filter2D();
    pmask->Show();
    return 0;
}

        效果图:7--OpenCV:图像基本操作之①截取②掩膜 操作_第3张图片

你可能感兴趣的:(OpenCV,opencv)