1. 程式人生 > >OpenCV獲取與設定畫素點的值的幾個方法

OpenCV獲取與設定畫素點的值的幾個方法

Code 1 :

int main()
{
    //新建一個uchar型別的單通道矩陣(grayscale image 灰度圖)
    Mat m(400, 400, CV_8U, Scalar(0));
    for (int col = 0; col < 400; col++)
    {
        for (int row = 195; row < 205; row++)
        {
            cout << (int)(*(m.data + m.step[0] * row + m.step[1] * col)) << "  ==> "
;
            //獲取第[row,col]個畫素點的地址並用 * 符號解析
            *(m.data + m.step[0] * row + m.step[1] * col) = 255;
            cout << (int)(*(m.data + m.step[0] * row + m.step[1] * col)) << endl;
        }
    }
    imshow("canvas", m);
    cvWaitKey();
    return 0;
}

Output 1 :

0  ==> 255
0  ==> 255
0  ==> 255
0  ==> 255
0  ==> 255
0  ==> 255
...

image

Code1只是演示了單通道的情況,對於多通道的例子,請看 Code2 然後再看 Code3。

Fn 2 :

使用 Mat::at 函式

  • 原型 template<typename _Tp> inline _Tp& Mat::at(…) //其中引數有多個,也就是說 at 函式有多個過載
  • 返回值為 Mat 型別, Mat 有個索引的過載,也就是 [] 符號的過載,用這個過載可以定位多通道資料,具體示例可以看下面程式碼

下面的程式碼把紅色通道值大於128的顏色的置為白色,左邊為原圖,右邊為處理過後的圖。

Code 2 :

int main()
{    
    Mat img = imread("lena.jpg");
    imshow("Lena Original", img);
    for (int row = 0; row < img.rows; row++)
    {
        for (int col = 0; col < img.cols; col++)
        {    
            /* 注意 Mat::at 函式是個模板函式, 需要指明引數型別, 因為這張圖是具有紅藍綠三通道的圖,
               所以它的引數型別可以傳遞一個 Vec3b, 這是一個存放 3 個 uchar 資料的 Vec(向量). 這裡
               提供了索引過載, [2]表示的是返回第三個通道, 在這裡是 Red 通道, 第一個通道(Blue)用[0]返回 */
            if(img.at<Vec3b>(row, col)[2] > 128)
                img.at<Vec3b>(row, col) = Vec3b(255, 255, 255);
        }
    }
    imshow("Lena Modified", img);
    cvWaitKey();
    return 0;
}

Output 2 :

image

Code 3 :

這段程式碼用的是 Fn1 的方式,效果和 Code 2 等價:

int main()
{    
    Mat img = imread("lena.jpg");
    imshow("Lena Original", img);
    for (int row = 0; row < img.rows; row++)
    {
        for (int col = 0; col < img.cols; col++)
        {
            //主要是這裡的程式碼
            if(*(img.data + img.step[0] * row + img.step[1] * col + img.elemSize1() * 2) > 128)
            {
                //[row, col]畫素的第 1 通道地址被 * 解析(blue通道)
                *(img.data + img.step[0] * row + img.step[1] * col) = 255;
                //[row, col]畫素的第 2 通道地址被 * 解析(green通道), 關於elemSize1函式的更多描述請見 Fn1 裡所列的博文連結
                *(img.data + img.step[0] * row + img.step[1] * col + img.elemSize1()) = 255;
                //[row, col]畫素的第 3 通道地址被 * 解析(red通道)
                *(img.data + img.step[0] * row + img.step[1] * col + img.elemSize1() * 2) = 255;
            }
        }
    }
    imshow("Lena Modified", img);
    cvWaitKey();
    return 0;
}

Output 3 = Output 2

Fn 3 :

使用 Mat 的一個模板子類 Mat_<typename _Tp> 的 ( ) 符號過載定位一個畫素

Code 4 :

int main()
{    
    Mat m(400, 400, CV_8UC3, Scalar(255, 255, 255));
    // m2 是 Mat_<Vec3b> 型別的, 因為 m 中元素的型別是 CV_8UC3, 可以用 Vec3b 儲存 3 個通道的值
    // 注意 Mat_<CV_8UC3> 這種寫法是錯誤的, 因為 CV_8UC3 只是一個巨集定義
    // #define CV_8UC3 CV_MAKETYPE(CV_8U, 3)
    Mat_<Vec3b> m2 = m;
    // for 迴圈畫一個紅色的實心圓
    for (int y = 0; y < m.rows; y++)
    {
        for (int x = 0; x < m.rows; x++)
        {
            if (pow(double(x-200), 2) + pow(double(y-200), 2) - 10000.0 < 0.00000000001)
            {
                // Mat_ 模板類實現了對()的過載, 可以定位到一個畫素
                m2(x, y) = Vec3b(0, 0, 255);
            }
        }
    }
    imshow("Image", m);
    cvWaitKey();
    return 0;
}

Output 4 : [ 看上去怎麼有點不爽失望]

image

Fn 4 :

使用 Mat::ptr 模板函式

Code 5 :

int main()
{    
    Mat m(400, 400, CV_8UC3, Scalar(226, 46, 166));
    imshow("Before", m);
    for (int row = 0; row < m.rows; row++)
    {
        if (row % 5 == 0)
        {
            // data 是 uchar* 型別的, m.ptr<uchar>(row) 返回第 row 行資料的首地址
            // 需要注意的是該行資料是按順序存放的,也就是對於一個 3 通道的 Mat, 一個畫素有
            // 有 3 個通道值, [B,G,R][B,G,R][B,G,R]... 所以一行長度為:
            // sizeof(uchar) * m.cols * m.channels() 個位元組
            uchar* data = m.ptr<uchar>(row);
            for (int col = 0; col < m.cols; col++)
            {
                data[col * 3] = 102; //第row行的第col個畫素點的第一個通道值 Blue
                data[col * 3 + 1] = 217; // Green
                data[col * 3 + 2] = 239; // Red
            }
        }
    }
    imshow("After", m);
    cout << (int)m.at<Vec3b>(0, 0)[0] << ','; //利用 Fn 1 介紹的方法輸出一下畫素值到控制檯
    cout << (int)m.at<Vec3b>(0, 0)[1] << ',';
    cout << (int)m.at<Vec3b>(0, 0)[2] << endl;
    cvWaitKey();
    return 0;
}

Output 5 :

image

本文轉載自:http://ggicci.blog.163.com/blog/static/21036409620126157403724/

相關推薦

OpenCV獲取設定方法

Code 1 : int main() { //新建一個uchar型別的單通道矩陣(grayscale image 灰度圖) Mat m(400, 400, CV_8U, Sca

獲取圖片每個的RGB並計算灰度

主要通過獲取本地的一張圖片,分析圖片每一畫素點的RGB值,由此獲得每一畫素點的灰度值,並對這些灰度值進行熵的計算。 import java.awt.BorderLayout; import java.awt.Color; import java.awt.event.*; i

opencv中對影象訪問的三種方法利用程式進行解讀

程式碼放到自己的工程中,執行就可以的 #include <opencv2\opencv.hpp> #include <opencv2\core\core.hpp> #include <opencv2\highgui\highgui.hpp> #includ

OpenCV的Mat操作

Mat資料結構,操作灰度影象畫素點:int gray_value = (int) image.at<uchar>(i , j) ;操作彩色影象畫素點:int color_value = (int) image.at<Vec3b>(i , j) [k];

一個為4位元組

【webkit的原始碼】https://github.com/WebKit/webkit/blob/master/Source/WebCore/html/HTMLCanvasElement.cpp#L365 在移動端是否耗記憶體比較大,手機解析度高dpr 比較大,比如iPhone

OpenCV 獲取方法

http://tmjfzy.blog.163.com/blog/static/6644702520126157403724/ Fn 1 : Code 1 : int main() { //新建一個uchar型別的單通道矩陣(grayscale image

使用Opencv獲取每個的RGB顏色分量/HSV顏色分量

一.  所需結構體CvScalar結構體介紹typedef struct CvScalar {   double val[4]; //BGRA   }CvScalar; 二. 所需函式cvG

opencv提取彩色影象所有的RGB方法實現

最近需要一個專案是對影象識別,學習了一下opencv。對opencv了一個簡單理解: 程式碼只能讀取已知影象大小的畫素RGB值,例如375*500,其他大小可將CvPoint pt2 = cvPoint(375,a)和for(a=0;a<=500;a++

OpenCV訪問的灰度

1.Mat矩陣數值的儲存方式             這裡以指標的方式訪問影象素為例          (1)單通道               定義一個單通道影象: cv::Mat img_1 = (320, 640, CV_8UC1, Sca

opencv學習筆記存取

我不想永遠是小明,我也想成為小紅。 椒鹽噪點:隨機的將部分畫素設定為白色或黑色。如果部分畫素丟失,那麼這種噪點就會出現。 cout是輸出,屬於iostream,格式:cout<< CV_[位數][帶符號與否][型別字首]C[通道數],如CV

影象讀取和賦

//取IplImage影象畫素值 int main() {     IplImage* src = cvLoad("filename",0); //-1預設讀取原通道,0 灰度圖,1彩色圖     if(src!=0)  &nb

opencv 位置描述的不同

Mat image, image_3c; image.create(Size(800, 600), CV_8UC1);//單通道 image_3c.create(Size(800, 600), CV_8UC3);//3通道 image.setTo(0); image_3c.setTo(0); imag

OpenCvSharp 得到Mat的

Vec3b value = image.At<Vec3b>(5, 100); image是Mat型別,得到第5行,第100列的畫素值。注意返回值的型別是Vec3b Vec3b value = image.Get<Vec3b>(5, 100); 與At的功能相似,

OpenCV---如何統計影象的分佈個數(6)

程式碼如下: import cv2 as cv import matplotlib.pyplot as plt import numpy as np def statistics(): src = cv.imread("D:/matplotlib/0.jpg") cv.imshow(

OpenCV—Python Numpy陣列()操作

一、遍歷訪問圖片每個畫素點,並修改相應的RGB def access_pixels(image): print(image.shape) height = image.shape[0]

opencv中輪廓內部的怎麼提取

pointPolygonTest(InputArray contour,Point2f pt,bool measureDist);cvPointPolygonTest(const CvArr*contour,CvPoi

OpenCV】訪問Mat影象中每個

轉載自https://blog.csdn.net/warrenwg/article/details/48056363 優化C++和OpenCv過程中,總結的若干技巧如下:  1 訪問Opencv的Mat格式時,需要注意訪問方式,其中使用C語言的【】操作符訪問最快,使用.At<&g

opencv修改影象的

本節知識點 1,讀寫影象 a,imread可以載入灰度圖或者RGB影象 b,imwrite儲存影象,型別由副檔名決定 2,讀寫影象的畫素 a,讀取灰度影象畫素點的值(CV_8UC1) Scalar i

OpenCV訪問Mat中每個

寫的很好,我就轉來了,不錯。 方法零:.ptr和[]操作符 Mat最直接的訪問方法是通過.ptr<>函式得到一行的指標,並用[]操作符訪問某一列的畫素值。 // using .ptr and [] void colorRed

Opencv Mat 類詳解以及基本讀取方法

class CV_EXPORTS Mat { public: //! default constructor Mat(); //! constructs 2D matrix of the specified size and type // (_type is CV_8UC1,