opencv圖像處理基礎 (《OpenCV編程入門--毛星雲》學習筆記一---五章)


#include <QCoreApplication> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp>

using namespace cv; int main() { Mat Valley = imread("/home/ttwang/Valley.jpg"); Mat ValleyLogo = imread("/home/ttwang/ValleyLogo.jpg"); namedWindow("[1] ValleyPic"); imshow("[1] ValleyPic",Valley); namedWindow("[2] ValleyLogo"); imshow("[2] ValleyLogo",ValleyLogo); Mat valleyROI; 
/******************實現兩個圖像混合****************************/
valleyROI
= Valley(Rect(800,350,ValleyLogo.cols,ValleyLogo.rows)); addWeighted(valleyROI,0.5,ValleyLogo,0.3,0.,valleyROI); namedWindow("valley+logo"); imshow("valley+logo",Valley); // imwrite("",Valley); waitKey(0); return 0; }



二、創建滑動條:createTrackbar()函數  (利用滑動條實現兩幅圖的Alpha混合

 1 #include <QCoreApplication>  //本人所用的IDE是QT,,終端編譯時不需要該聲明
 2 #include <opencv2/core/core.hpp>
 3 #include <opencv2/highgui/highgui.hpp>
 4 #include <opencv2/imgproc/imgproc.hpp>
 5 using namespace cv;  6 
 7 #define WINDOW_NAME "[Alpha]"   //窗口名的宏定義
 8 
 9 const int g_nMaxAlphaValue = 100; 10 int g_nAlphaValueSlider; 11 double g_dAlphaValue; 12 double g_dBetaValue; 13 
14 Mat g_srcImage1; 15 Mat g_srcImage2; 16 Mat g_dstImage; 17 /**********響應滑動條的回調函數*************/
18 void on_Trackbar( int ,void*) 19 { 20     g_dAlphaValue = (double) g_nAlphaValueSlider/g_nMaxAlphaValue; 21     g_dBetaValue = (1.0 - g_dAlphaValue); 22     //根據Alpha beta的值進行線性混合
    addWeighted(g_srcImage1,g_dAlphaValue,g_srcImage2,g_dBetaValue,0.0,g_dstImage); 23 imshow(WINDOW_NAME,g_dstImage); 24 } 25 26 int main() 27 { 28 g_srcImage1 = imread("/home/ttwang/11.jpg");  //兩幅圖的尺寸要相同,否則出現如下圖錯誤 29 g_srcImage2 = imread("/home/ttwang/12.jpg"); 30 31 g_nAlphaValueSlider = 70; 32 namedWindow(WINDOW_NAME,1); 33 34 char TrackbarName[50]; 35 sprintf(TrackbarName,"透明值 %d", g_nMaxAlphaValue); 36 createTrackbar(TrackbarName,WINDOW_NAME, &g_nAlphaValueSlider, g_nMaxAlphaValue,on_Trackbar); 37 on_Trackbar(g_nAlphaValueSlider,0); 38 39 waitKey(0); 40 return 0; 41 42 }

 由於程序不是直接粘貼過來的,按該程序進行編譯時候,總出現錯誤,可以參考下面的鏈接  感謝分享





 

 

三、鼠標操作:SetMouseCallback()函數

 

#include <QCoreApplication>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;

#define WINDOW_NAME "[Program window]"   //為窗口標題定義的宏

/******************全局函數的聲明********************/
void on_MouseHandle(int event,int x, int y, int flags, void* param);
void DrawRectangle(cv::Mat& img, cv::Rect box);
void ShowHelpText();

/******************全局變量聲明*********************/
Rect g_rectangle;
bool g_bDrawingBox = false;//是否繪制
RNG g_rng(12345);



int main()
{
  g_rectangle = Rect(-1,-1,0,0);
  Mat srcImage(600,800,CV_8UC3),tempImage;
  srcImage.copyTo(tempImage);
  g_rectangle = Rect(-1,-1,0,0);
  srcImage = Scalar::all(0);

  //設置鼠標操作回調函數
  namedWindow(WINDOW_NAME);
  setMouseCallback(WINDOW_NAME,on_MouseHandle,(void*)&srcImage);
  while(1)
  {
     srcImage.copyTo(tempImage);  //復制源圖到臨時變量
     if(g_bDrawingBox) DrawRectangle(tempImage,g_rectangle);//當繪制標識符為真,進行繪制
     imshow(WINDOW_NAME,tempImage);
     if(waitKey(10) == 27) break;    //按下Esc,程序退出
  }
   return 0;
}

/*********鼠標回調函數,根據不同的鼠標事件進行不同的操作*******************/
void on_MouseHandle(int event, int x, int y, int flags, void *param)
{
    Mat& image = *(cv::Mat*) param;
    switch (event)
    {
      //鼠標移動消息
      case EVENT_MOUSEMOVE:
      {
        if(g_bDrawingBox)//如果是否進行繪制額標識符為真,則記錄下長和寬到RECT型變量中
        {
            g_rectangle.width = x - g_rectangle.x;
            g_rectangle.height = y- g_rectangle.y;
        }
      }
        break;
      //左鍵按下消息
      case EVENT_LBUTTONDOWN:
      {
          g_bDrawingBox = true;
          g_rectangle = Rect(x,y,0,0);//記錄起始點
      }
        break;
      //左鍵抬起消息
      case EVENT_LBUTTONUP:
      {
          g_bDrawingBox = false;  //置標識符為false
          //對寬和高小於0的進行處理
          if(g_rectangle.width < 0)
          {
              g_rectangle.x += g_rectangle.width;
              g_rectangle.width *= -1;
          }
          if(g_rectangle.height < 0)
          {
              g_rectangle.y += g_rectangle.height;
              g_rectangle.height *= -1;
          }
          //調用回調函數進行繪制
          DrawRectangle( image, g_rectangle);
      }
        break;

    }
}

/********************自定義的矩形繪制函數DrawRectangle() ********************/
void DrawRectangle(cv::Mat& img, cv::Rect box)
{
    rectangle(img,box.tl(),box.br(),Scalar(g_rng.uniform(0,255),g_rng.uniform(0,255),g_rng.uniform(0,255)));
}



 四章、OpenCV數據結構與基本繪圖

1. Mat M(2,2,CV_8UC3,Scalar(0,0,255)); //使用Mat()構造函數創建Mat對象

 兩行兩列、CV_8UC3: CV_[位數][帶符號與否]C[通道數] Scalar是個short類型的向量,可以使用指定的值來初始化矩陣

2.Mat M;  M.create(4,4,CV_8UC3);  //使用create()函數創建Mat對象,,此方法不能為矩陣設初值

3.顏色的表示類:Scalar()是具有四個元素的數組,,第四個用不到,則不寫 格式如下:

        Scalar(a, b,  c)定義的RGB顏色值:紅色分量c 綠色分量b  藍色分量 a

4.尺寸的表示類: Size()  常用格式: Size(5,5)表示構造出的Size高度和寬度都為5

5.矩形的表示類: Rect類的成員有x,y,width,height,分別為左上角的坐標和矩形的寬、高

         格式: Rect rect(0,0,200,400)

6.顏色空間轉換:cvtColor()函數  格式:cvtColor(InputArraysrc, OutputArray dst, int code, int dstCn=0) 

                 第一個參數:輸入圖像;

                 第二個參數:輸出圖像;

                 第三個參數:顏色空間轉換的標識符; (詳見:P98)

                                                                第四個參數:目標圖像的通道數,若為0,則表示其取源圖像的通道數。

7.基本圖型的繪制涉及的函數:   (通過例程學習 P100) 

              繪制直線的line函數

              繪制橢圓的ellipse函數

              繪制矩形的rectangle函數

              繪制圓的circle函數

              繪制填充的多邊形的fillPloy函數


 

第五章 core組件進階

1.計時函數:  getTickCount()和getTickFrequency()

       getTickCount()函數返回CPU自某個事件以來走過的時鍾周期數

       getTickFrequency()函數返回CPU一秒鍾走過的周期數

顯然: 二者結合可以實現對某種圖像處理方法的計時

double time0 = static_cast<double>(getTickCount());  //記錄起始時間
 time0= ((double)getTickCount() - time0)/getTickFrequency();////計算運行時間並輸出
 cout<<"\t此方法運行時間為:"<<time0<<""<<endl;  //輸出運行時間

 

2.訪問圖像中像素的幾種方法 (簡單介紹,具體P110)

需要先明白以下知識: 

(1) Mat類的公有成員變量cols和rows給出了圖像的寬和高

   image.cols       image.rows

(2)    Mat類的成員函數channels()用於返回圖像的通道數;

  灰度圖像通道數1,彩色圖像通道數為3  image.channels()

(4)    每一行的像素個數= image.cols*image.channels()       

a.直接遍歷,使用Mat里的成員函數data

/*********只用於訪問連續空間********/ Mat mat (3000,4000,CV_8UC3) int es = mat.eleSize();   //定義步長,因為定義為3通道的,實質該值為3
int size = mat.rows*mat.cols*es; for(int i = 0; i < size; i += es) { mat.data[i] = 255;     // B通道
  mat.data[i+1] = 0;    // G通道
  mat.data[i+2] = 0;   //  R通道
}

b.直接訪問不連續空間

for (int row = 0; row < mat.rows; row++) { for (int col = 0; col < mat.cols; col++) { (&mat.data[row*mat.step])[col*es] = 0; (&mat.data[row*mat.step])[col*es + 1] = 0; (&mat.data[row*mat.step])[col*es + 2] = 255; } }

c.通過opencv ptr模板函數遍歷

 1 for (int row = 0; row < mat.rows; row++)  2 {  3   for (int col = 0; col < mat.cols; col++)  4   {  5      Vec3b *c = mat.ptr<Vec3b>(row,col);  6      c->val[0] = 0;
 8      c->val[1] = 255
10      c->val[2] = 0;     } 13 }

c.通過at遍歷

 1   for (int row = 0; row < mat.rows; row++)  2  {  3     for (int col = 0; col < mat.cols; col++)  4  {  5       Vec3b &m = mat.at<Vec3b>(row, col);  6       m[0] = 0;  7       m[1] = 0;  8       m[2] = 255;  9  } 10 }

 d.通過迭代器遍歷

1   auto it = mat.begin<Vec3b>();   //自動類型匹配auto
2   auto it_end = mat.end<Vec3b>(); 3   for (; it != it_end; it++) 4   { 5    (*it).val[0] = 0; 6    (*it).val[1] = 0; 7    (*it).val[2] = 255; 8   }

 

3.感興趣區域ROI /******表示方法一 Rect矩形區域*******/ Mat imageROI imageROI = image(Rect(500,250,logo.cols,logo.rows));  //image為已經載入好的圖片

/******表示方法二 Range指定感興趣的行和列********/

imageROI = image(Range(250,250+logoImage.rows),Range(200,200+logoImage.cols)); //image為已經載入好的圖片
 
4.利用addWeighted可實現圖像線性混合 數學公式: dst = src1[I] * alpha + src2[I]*beta + gamma      (P117)
5.分離顏色通道、多通道圖像混合 通道分離:split()函數,將一個3通道圖像轉換成3個單通道 通道合並:merge()函數 ###例程:(課本P127,以多通道混合-藍色分量部分為例) ###平台:QT5.7.1+OpenCV3.2.0 ###時間:2017年12月11日 /********建立QT控制台程序*********/ #include <QCoreApplication> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <iostream>
using namespace std; using namespace cv; //全局函數聲明
bool MultiChannelBlending(); int main() { if(MultiChannelBlending()) { cout << endl << "\n運行成功,得到目標圖像" << endl; } waitKey(0); return 0; } /*********多通道混合的實現函數*********/
bool MultiChannelBlending() { Mat srcImage; Mat logoImage; vector<Mat> channels; /********** 藍色分量 *************/ Mat imageBlueChannel; logoImage = imread("/home/ttwang/Valley_logo.jpg",0);//一定要讀入會灰度圖像,不然addWeighted()會因為類型不匹配而報錯
    srcImage = imread("/home/ttwang/Valley.jpg"); split(srcImage,channels); //將一個3通道圖像轉換成3個單通道
    imageBlueChannel = channels.at(0); //將原圖的藍色通道引用返回給imageBlueChannel
    addWeighted(imageBlueChannel(Rect(500,250,logoImage.cols,logoImage.rows)),1.0,logoImage,0.5,0.,imageBlueChannel(Rect(500,250,logoImage.cols,logoImage.rows))); merge(channels,srcImage);//將三個單通道重新合並成一個三通道
    namedWindow("src+LogoBlue"); imshow("src+LogoBlue",srcImage); /*******綠色分量 ******/ Mat imageGreenChannel; logoImage = imread("/home/ttwang/Valley_logo.jpg",0); srcImage = imread("/home/ttwang/Valley.jpg"); split(srcImage,channels); //將一個3通道圖像轉換成3個單通道
     imageGreenChannel = channels.at(1); addWeighted(imageGreenChannel(Rect(500,250,logoImage.cols,logoImage.rows)),1.0,logoImage,0.5,0.0,imageGreenChannel(Rect(500,250,logoImage.cols,logoImage.rows))); merge(channels,srcImage);//將三個單通道重新合並成一個三通道
     namedWindow("src+LogoGreen"); imshow("src+LogoGreen",srcImage); /*******紅色分量 ******/ Mat imageRedChannel; logoImage = imread("/home/ttwang/Valley_logo.jpg",0); srcImage = imread("/home/ttwang/Valley.jpg"); split(srcImage,channels); //將一個3通道圖像轉換成3個單通道
      imageRedChannel = channels.at(2); addWeighted(imageRedChannel(Rect(500,250,logoImage.cols,logoImage.rows)),1.0,logoImage,0.5,0.0,imageRedChannel(Rect(500,250,logoImage.cols,logoImage.rows))); merge(channels,srcImage);//將三個單通道重新合並成一個三通道
      namedWindow("src+LogoRed"); imshow("src+LogoRed",srcImage); return true; }

 

6.圖像對比度、亮度調整 公式: g(i,j)=a*f(i,j)+b; (opencv控制圖像對比度和亮度的理論公式) 參數a(a>0)通常被成為增益,控制圖像的對比度 參數b稱為偏置,控制圖像的亮度 訪問圖片中的像素:(使用三個for循環,語法:image.at<Vec3b>(y,x)[c]) 其中,y是像素所在的行,x是像素所在的列,c是B、G、 R(對應0、12

 

7.離散傅里葉變換(詳細參照課本P135) 參考資料及函數說明,參照下面的鏈接:  opencv2教程之離散型傅里葉變換

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

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



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