歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

OpenCV矩陣Mat的運算——在DIP作業(圖像增強)中出現問題解決

本次作業是要求不用OpenCV中的庫函數,選擇兩張不好的圖片對其進行圖像增強。我選了一張過白的image,想通過指數變換的方法對其進行圖像增強。作為初級學習OpenCV 運用者,由於OpenCV沒怎麼編過程序,所以一開始就遇到了很多問題。

--------------------------------------分割線 --------------------------------------

編輯推薦

Ubuntu Linux下安裝OpenCV2.4.1所需包 http://www.linuxidc.com/Linux/2012-08/68184.htm

Ubuntu 12.04 安裝 OpenCV2.4.2 http://www.linuxidc.com/Linux/2012-09/70158.htm

CentOS下OpenCV無法讀取視頻文件 http://www.linuxidc.com/Linux/2011-07/39295.htm

Ubuntu 12.04下安裝OpenCV 2.4.5總結 http://www.linuxidc.com/Linux/2013-06/86704.htm

Ubuntu 10.04中安裝OpenCv2.1九步曲 http://www.linuxidc.com/Linux/2010-09/28678.htm

基於QT和OpenCV的人臉識別系統 http://www.linuxidc.com/Linux/2011-11/47806.htm

--------------------------------------分割線 --------------------------------------

1 Mat 的數據類型導致運算的錯誤

下面是主程序:

#include <iostream>
#include <highgui.h>
#include <cv.h>
#include <math.h>
using namespace std;
using namespace cv;
#define POWER_a 3.0    //冪指數變換的指數大小
void PowerTransfor(Mat image);                  //利用指數變換對過白圖片的處理函數
int main ()
{
 const char *image_name1="E:\\Program\\DIP\\HW_1_enhance\\guobai.jpg";
 Mat img;          //save the image that was processed
 img = imread(image_name1,CV_LOAD_IMAGE_GRAYSCALE);     //只讀取灰度分量
 cout<<"the size of img is "<<img.rows<<"X"<<img.cols<<"  "<<"channels is "<<img.channels()<<endl;  //檢驗是1通道的
 cvNamedWindow("ORIGINAL PICTURE",CV_WINDOW_AUTOSIZE);
 imshow("ORIGINAL PICTURE",img);
 PowerTransfor(img);
 return 0;
}

下面就是指數變換函數:

/*************對過白的圖片進行處理*******************/
void PowerTransfor(Mat image)
{
 Mat newImage(image.size(),CV_64FC1);
 double pixMax = 0.0;
 double pixMin = 255.0;
 for (int i = 0; i < image.rows; i++)
 {
  for (int j = 0; j < image.cols; j++)
  {
   newImage.at<double>(i,j) = pow(image.at<uchar>(i,j),POWER_a);
   if (newImage.at<double>(i,j) >= pixMax)
   {
    pixMax = newImage.at<double>(i,j);

   }
   if (newImage.at<double>(i,j) <= pixMin)
   {
    pixMin = newImage.at<double>(i,j);
   }

  }
 }
 for (int i = 0; i < image.rows; i++)
 {
  for (int j = 0; j < image.cols; j++)
  {
   image.at<uchar>(i,j) = (uchar)(newImage.at<double>(i,j)/(pixMax - pixMin)*255);  //將處理後的值歸化到(0~255)中.
  }

 }
 cvNamedWindow("PowerTransfor PICTURE",CV_WINDOW_AUTOSIZE);
 imshow("PowerTransfor PICTURE",image);
 cvWaitKey(0);
}

1.1 通過imread讀取圖像得到的矩陣img,這個矩陣的元素是uchar類型(0:255)的。所以有必要對各種類型的字節數有個了解。

1.2 需要一個保存處理後的像素的矩陣,這個矩陣需要和img的size一致,同時,數據類型又要大於uchar的類型,我們可以用float或者double類型。

定義這個同型矩陣的方法:

Mat newImage(image.size(),CV_32FC1);

或者:

Mat newImage(image.rows,image.cols,CV_32FC1);//也可以

錯誤的方法;

Mat newImage(image.size,CV_32FC1);//size需要括號。

Mat newImage=img.clone(); //得到的是和img同類型的,元素也是相同的,所以不行。

Mat newImage(image.size(),double);//切記,類型是opencv規定的類型,不是C++中的類型double之類的。

Copyright © Linux教程網 All Rights Reserved