opencv 學習歷程

部分完整代碼在
opencv example

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小數點位數
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章