1. 程式人生 > >opencv 學習歷程

opencv 學習歷程

opencv實現圖片加法

addWeighted( src1, alpha, src2, beta, 0.0, dst);
代表
dst=α×src1+β×src2+γdst =\alpha \times src1 + \beta\times src2 + \gamma
在本例子中
gamma=0,src1,src2gamma=0, src1, src2代表兩幅不同圖片

opencv實現圖片灰度值改變(Brightness and contrast adjustments)

g(i,j)=αf(i

,j)+βg(i, j) = \alpha * f(i, j) + \beta

    for( int y = 0; y < image.rows; y++ ) {
        for( int x = 0; x < image.cols; x++ ) {
            for( int c = 0; c < image.channels(); c++ ) {
                new_image.at<Vec3b>(y,x)[c] =
                  saturate_cast<uchar>( alpha*image.at<Vec3b>(y,x)[c] + beta );
                  //saturate_cast防止灰度值溢位
            }
        }
    }

採用look up table方法的話

    Mat lookUpTable(1, 256, CV_8U);
    uchar* p = lookUpTable.ptr();
    for( int i = 0; i < 256; ++i)
        p[i] = saturate_cast<uchar>(i*alpha + beta);
    Mat res = img.clone();
    LUT(img, lookUpTable, res);

File Input and Output using XML and YAML files

一個純c++ opencv程式和一個混合c c++opencv程式區別

opencv繪圖函式

  1. 畫線line()
  2. 橢圓ellipse()
  3. 矩形rectangle()
  4. 圓 circle()
  5. 多邊形fillPoly()

opencv隨機數

RNG rng;
b = rng; //產生64位整數
x = rng.uniform(a, b); //產生a,b 之間的一個值
y = rng.gaussian(sigma); //產生一個方差為sigma 均值位0滿足高斯分佈的值

opencv與文字有關函式

  1. opencv顯示文字函式:putText();
  2. opencv getTextSize()獲取輸入文字的大小

Smoothing the image

  1. 均值濾波
    blur( src, dst, Size( 3, 3 ), Point(-1,-1) );
  2. 高斯濾波
GaussianBlur( src, dst, Size( 3, 3 ), 0, 0 );
//Size必須是奇數,否則要根據x, y方向的方差計算Size
  1. 中值濾波
 medianBlur ( src, dst, i );
 //中值濾波濾波器必須位正方形
  1. Bilateral filter雙邊濾波,可以理解為高斯濾波(空間距離決定)+鄰域灰度資訊(畫素差決定),可以更好保留影象邊緣的細節
bilateralFilter(InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace, int borderType=BORDER_DEFAULT )
//d 表示在過濾過程中每個畫素鄰域的直徑範圍
//sigmaColor: 顏色空間過濾器的sigma值,這個引數的值大,表明該畫素鄰域內有月寬廣的顏色會被混合到一起
//sigmaSpace:座標空間中濾波器的sigma值,如果該值較大,則意味著顏色相近的較遠的畫素將相互影響

形態學處理: 膨脹Dilation和腐蝕Erosion

  1. dilation: The value of the output pixel is the maximum value of all the pixels that fall within the structuring element’s size and shape
  2. Erosion: The vise versa applies for the erosion operation. The value of the output pixel is the minimum value of all the pixels that fall within the structuring element’s size and shape
  3. 在數字影象中,越白代表灰度值越大,因而在一些情況下,形態學處理需要考慮反色
  4. Hit-or-Miss theory

###影象金字塔,包括高斯金字塔和laplace金字塔,實現上取樣和下采樣

pyrUp( src, src, Size( src.cols*2, src.rows*2 ) //上取樣
pyrDown( src, src, Size( src.cols/2, src.rows/2 ) )//下采樣

閾值化

threshold ( InputArray src, OutputArray dst, double thresh, double maxval, int type )

sobel運算元 相當於一階濾波器

    Sobel(src_gray, grad_x, ddepth, 1, 0, ksize, scale, delta, BORDER_DEFAULT);
    Sobel(src_gray, grad_y, ddepth, 0, 1, ksize, scale, delta, BORDER_DEFAULT);
    convertScaleAbs(grad_x, abs_grad_x);
    convertScaleAbs(grad_y, abs_grad_y);
    addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad);

laplace運算元 二階導數為零

Laplacian( src_gray, dst, ddepth, kernel_size, scale, delta, BORDER_DEFAULT );

Canny Edge Detector sobel運算元的進化版

  1. 高斯濾波
  2. 同時考慮x y 和不同角度上梯度資訊
  3. 應用非極大值抑制出去非邊緣的地方
  4. 雙邊閾值
Canny( soure_img, edges, lowThreshold, highThreshold, kernel_size );

hough line transoform 霍夫變換

霍夫變換的遠離參照opencv官網,在這裡不加贅述https://docs.opencv.org/master/d9/db0/tutorial_hough_lines.html
opencv中提供了兩種計算霍夫變換的方法

  1. 標準霍夫變換,返回 rrθ\theta
  2. 概率霍夫變換,更高效,返回在同一直線上的點; HoughLinesP(),返回的是點的座標(x0,y0,x1,y1)(x_{0}, y_{0}, x{1}, y_{1})
    標準霍夫變換程式碼
//霍夫變換針對二值影象```
Canny( soure_img, edges, lowThreshold, highThreshold, kernel_size );
//儲存霍夫變換輸出結果
 vector<Vec2f> lines; 
 //引數含義為原影象,結果, 引數r解析度, theta解析度 CV_PI/180代表1度, 檢測是一根線閾值即有多少個點共線才算一條直線, 兩個預設引數
 HoughLines(dst, lines, 1, CV_PI/180, 150, 0, 0 ); // runs the actual detection
 //繪圖
 // size_t是一種資料相關的無符號型別,它被設計得足夠大以便能夠記憶體中任意物件的大小
     for( size_t i = 0; i < lines.size(); i++ )
    {
        float rho = lines[i][0], theta = lines[i][1];
        Point pt1, pt2;
        double a = cos(theta), b = sin(theta);
        double x0 = a*rho, y0 = b*rho;
        pt1.x = cvRound(x0 + 1000*(-b));
        pt1.y = cvRound(y0 + 1000*(a));
        pt2.x = cvRound(x0 - 1000*(-b));
        pt2.y = cvRound(y0 - 1000*(a));
        line( cdst, pt1, pt2, Scalar(0,0,255), 3, LINE_AA);
        }
//中間加上了1000的是因為HoughLines相當於返回了直線的斜率和常數,需要找出直線上兩個點,這裡相當於取了間隔為2000的兩個點

概率霍夫變換程式碼

//儲存輸出結果
    vector<Vec4i> linesP; 
    //最後三個閾值含義 第一個是多少個點位於同一條直線;第二個是直線的最短長度;第三個是兩天直線的gap
    HoughLinesP(dst, linesP, 1, CV_PI/180, 50, 50, 10 ); 
    //繪圖
        for( size_t i = 0; i < linesP.size(); i++ )
    {
        Vec4i l = linesP[i];
        line( cdstP, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0,0,255), 3, LINE_AA);
    }

Hough Circle Transform

void HoughCircles(InputArray image,OutputArray circles, int method, double dp, double minDist, double param1=100, double param2=100, int minRadius=0,int maxRadius0 )
// circles 包括 x,y, r
// method 目前只有HOUGH_GRADIENT一種
// dp=1 表示霍夫空間和原圖解析度一致, dp=2為一半 以此類推
// minDist eg gray.rows/16 檢測出圓心最小距離
// param1 Canny edge detector閾值
// param2 有多少個點位於該圓閾值
// min_radius, max_radius 半徑最大最小

a example:
    HoughCircles(gray, circles, HOUGH_GRADIENT, 1,
                 gray.rows/16, 
                 100, 30, 1, 30)         
//畫圓圈函式
cvCircle(CvArr* img, CvPoint center, int radius, CvScalar color, int thickness=1, int lineType=8, int shift=0)
//color定義 Scalar(B, G, R)
//shift小數點位數