1. 程式人生 > >OpenCV--矩陣的掩膜操作

OpenCV--矩陣的掩膜操作

所謂掩膜其實就是一個矩陣,然後根據這個矩陣重新計算圖片中畫素的值。
掩膜主要有以下用途:

  • 提取感興趣區,用預先製作的感興趣區掩模與待處理影象相乘,得到感興趣區影象,感興趣區內影象值保持不變,而區外影象值都為0。
  • 遮蔽作用,用掩模對影象上某些區域作遮蔽,使其不參加處理或不參加處理引數的計算,或僅對遮蔽區作處理或統計。
  • 結構特徵提取,用相似性變數或影象匹配方法檢測和提取影象中與掩模相似的結構特徵。
  • 特殊形狀影象的製作。

掩膜操作實現影象對比度的提高:

影象畫素指標的獲取:

Mat.ptr<uchar>(row):獲取第row行的影象畫素指標。影象的行數從0開始計數

獲取點P(row,col)的畫素值:P(row.col
)= Mat.ptr<uchar>(row)[col]

使用的掩膜:
這裡寫圖片描述

紅色是中心元素I(i,j)。掩膜操作公式:

I(i,j)=5I(i,j)[I(i1,j)+I(i+1,j)+I(i,j1)+I(i,j+1)]
用此掩膜從上至下,從左至右對影象進行操作,得到的影象就是增強對比度的影象。

例項程式碼:

void KernelOper(){
    Mat src,dest;
    src = imread("girl.jpg");
    if(!src.data){
        cout << "檔案開啟失敗" << endl;
        return
; } namedWindow("掩膜操作前",WINDOW_AUTOSIZE); imshow("掩膜操作前",src); dest = Mat::zeros(src.size(),src.type());//生成一個和源影象大小相等型別相同的全0矩陣 int cols = (src.cols-1)*src.channels();//獲取影象的列數,一定不要忘記影象的通道數 int rows = src.rows;//獲取影象的行數 int offsetx = src.channels(); for (int row = 1; row < rows-1
;row++){ uchar* previous = src.ptr<uchar>(row-1); uchar* current = src.ptr<uchar>(row); uchar* next = src.ptr<uchar>(row+1); uchar* output = dest.ptr<uchar>(row); for (int col = offsetx; col < cols; col++){ output[col] = 5*current[col] - (previous[col]+next[col]+current[col-1]+current[col+1]); } } namedWindow("掩膜操作後",WINDOW_AUTOSIZE); imshow("掩膜操作後",dest); cvWaitKey(); }

這裡寫圖片描述
我們可以看見掩膜操作後的影象對比度明顯提高了,但是美中不足的是出現了一些不好的小斑點。這是因為這項畫素點的值的範圍不在0~255之間了。
解決方法:
使用函式saturate_cast(畫素值)
這個函式的作用就是確保RGB的值在0~255之間。
saturate_cast(-100)返回0;
saturate_cast(100)返回100;
saturate_cast(280)返回255。
新增上:

output[col] = saturate_cast<uchar>( 5*current[col] - (previous[col]+next[col]+current[col-1]+current[col+1])); 

這裡寫圖片描述
完美!!

OpenCV提高了函式filter2D來實現掩膜操作:

定義掩膜:

Mat kernel = (Mat<uchar>(3,3)<<0,-1,0,-1,5,-1,0,-1,0);
void KernelOper2(){
    Mat src,dest;
    src = imread("girl.jpg");
    if(!src.data){
        cout << "檔案開啟失敗" << endl;
        return ;
    }
    namedWindow("掩膜操作前",CV_WINDOW_AUTOSIZE);
    imshow("掩膜操作前",src);

    Mat kernel = (Mat_<char>(3,3)<<0,-1,0,-1,5,-1,0,-1,0);//定義掩膜
    //呼叫filter2D
    filter2D(src,dest,src.depth(),kernel);

    namedWindow("掩膜操作後",CV_WINDOW_AUTOSIZE);
    imshow("掩膜操作後",dest);
    cvWaitKey();
}

這裡寫圖片描述