OpenCV——使用ROI進行圖像切割


ROI(region of interest)——感興趣區域。

1.用途

這個區域是圖像分析所關注的重點。圈定這個區域,以便進行進一步的處理。而且,使用ROI指定

想讀入的目標,可以減少處理時間,增加精度,給圖像處理帶來不小的便利。

2.定義ROI方法

  • 使用表示矩陣區域的Rect。

它指定矩陣的左上角坐標(構造函數的前兩個參數)和矩陣的長寬(構造函數的后兩個參數)以定義一個矩陣區域。

// 定義一個Mat類型並給定其設定的區域
Mat imageROI;
// 方法一
imageROI = image(Rect(500, 250, logo.cols, logo.rows));
  • 指定感興趣行或列的范圍(Range)。

Range是指從起索引到終止索引(不包括終止索引)的一連串連續序列。cRange可以用來定義Range。如果使用Range來定義ROI,那么前例中定義ROI的代碼可以重寫為:

// 方法二
imageROI = image( Range(250, 250+logoImage.rows), 
Range(200, 200+logoImage.cols));

 3.切割具體步驟

  • 將要切割下的圖像區域局部設置為ROI
void cvSetImageROI(IplImage* image,CvRect rect);
  • 創建一個與切割圖像大小相同的新圖像
IplImage* cvCreateImage( CvSize size, int depth, int channels );
    depth 圖像元素的位深度,可以是下面的其中之一:
   
IPL_DEPTH_8U 無符號8位整型
IPL_DEPTH_8S 有符號8位整型
IPL_DEPTH_16U 無符號16位整型
IPL_DEPTH_16S 有符號16位整型
IPL_DEPTH_32F 單精度浮點數
IPL_DEPTH_64F 雙精度浮點數
   

 

    channels 每個元素(像素)通道數.可以是 1, 2, 3 或 4.通道是交叉存取的
  • 將原圖像復制到新圖像中
void cvCopy( const CvArr* src, CvArr* dst, const CvArr* mask=NULL ); 

     操作掩碼是8比特單通道的數組,它指定了輸出數組中被改變的元素。函數cvCopy從輸入數組中復制選定的成分到輸出數組:

    如果mask(I)!=0,則dst(I)=src(I)。

    如果輸入輸出數組中的一個IplImage類型的話,其ROI和COI將被使用。輸入輸出數組須是同樣的類型、維數和大小。函數也可以用來復制散列數組(這種情況下不支持mask)。

  • 釋放ROI區域
cvResetIamgeROI(src);

4.實例
  如何利用ROI將一幅圖加到另一幅圖的指定位置。

  通過一個圖像掩碼,直接將插入處的像素設置為插入圖像的像素值,這樣效果會很逼真。

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>

using namespace cv;
using namespace std;

bool  ROI_AddImage();
bool  LinearBlending();
bool  ROI_LinearBlending();
void   ShowHelpText();

int main(   )
{
    system("color 6F");

    if(ROI_AddImage( )&& LinearBlending( )&&ROI_LinearBlending( ))
    {
        cout<<endl<<"\n運行成功,得出了需要的圖像";
    }

    waitKey(0);
    return 0;
}




//----------------------------------【ROI_AddImage( )函數】----------------------------------
// 函數名:ROI_AddImage()
//    描述:利用感興趣區域ROI實現圖像疊加
//----------------------------------------------------------------------------------------------
bool  ROI_AddImage()
{

    // 【1】讀入圖像
    Mat srcImage1= imread("dota_pa.jpg");
    Mat logoImage= imread("dota_logo.jpg");
    if( !srcImage1.data ) { printf("讀取srcImage1錯誤~! \n"); return false; }
    if( !logoImage.data ) { printf("讀取logoImage錯誤~! \n"); return false; }

    // 【2】定義一個Mat類型並給其設定ROI區域
    Mat imageROI= srcImage1(Rect(200,250,logoImage.cols,logoImage.rows));

    // 【3】加載掩模(必須是灰度圖)
    Mat mask= imread("dota_logo.jpg",0);

    //【4】將掩膜拷貝到ROI
    logoImage.copyTo(imageROI,mask);

    // 【5】顯示結果
    namedWindow("<1>利用ROI實現圖像疊加示例窗口");
    imshow("<1>利用ROI實現圖像疊加示例窗口",srcImage1);

    return true;
}


//---------------------------------【LinearBlending()函數】-------------------------------------
// 函數名:LinearBlending()
// 描述:利用cv::addWeighted()函數實現圖像線性混合
//--------------------------------------------------------------------------------------------
bool  LinearBlending()
{
    //【0】定義一些局部變量
    double alphaValue = 0.5; 
    double betaValue;
    Mat srcImage2, srcImage3, dstImage;

    // 【1】讀取圖像 ( 兩幅圖片需為同樣的類型和尺寸 )
    srcImage2 = imread("mogu.jpg");
    srcImage3 = imread("rain.jpg");

    if( !srcImage2.data ) { printf("讀取srcImage2錯誤! \n"); return false; }
    if( !srcImage3.data ) { printf("讀取srcImage3錯誤! \n"); return false; }

    // 【2】進行圖像混合加權操作
    betaValue = ( 1.0 - alphaValue );
    addWeighted( srcImage2, alphaValue, srcImage3, betaValue, 0.0, dstImage);

    // 【3】顯示原圖窗口
    imshow( "<2>線性混合示例窗口【原圖】", srcImage2 );
    imshow( "<3>線性混合示例窗口【效果圖】", dstImage );

    return true;

}

//---------------------------------【ROI_LinearBlending()】-------------------------------------
// 函數名:ROI_LinearBlending()
// 描述:線性混合實現函數,指定區域線性圖像混合.利用cv::addWeighted()函數結合定義
//              感興趣區域ROI,實現自定義區域的線性混合
//--------------------------------------------------------------------------------------------
bool  ROI_LinearBlending()
{

    //【1】讀取圖像
    Mat srcImage4= imread("dota_pa.jpg",1);
    Mat logoImage= imread("dota_logo.jpg");

    if( !srcImage4.data ) { printf("讀取srcImage4錯誤~! \n"); return false; }
    if( !logoImage.data ) { printf("讀取logoImage錯誤~! \n"); return false; }

    //【2】定義一個Mat類型並給其設定ROI區域
    Mat imageROI;
    //方法一
    imageROI= srcImage4(Rect(200,250,logoImage.cols,logoImage.rows));
    //方法二
    //imageROI= srcImage4(Range(250,250+logoImage.rows),Range(200,200+logoImage.cols));

    //【3】將logo加到原圖上
    addWeighted(imageROI,0.5,logoImage,0.3,0.,imageROI);

    //【4】顯示結果
    imshow("<4>區域線性圖像混合示例窗口",srcImage4);

    return true;
}

 

 

參考:《OpenCV3編程入門》  毛星雲 著


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM