天天看點

opencv圖像像素值讀取

說到圖像像素,肯定要先認識一下圖像中的坐标系長什麼樣。

 1. 坐标體系中的零點坐标為圖檔的左上角,X軸為圖像矩形的上面那條水準線;Y軸為圖像矩形左邊的那條垂直線。該坐标體系在諸如結構體Mat,Rect,Point中都是适用的。(OpenCV中有些資料結構的坐标原點是在圖檔的左下角,可以設定的)。

 2. 在使用image.at<TP>(x1, x2)來通路圖像中點的值的時候,x1并不是圖檔中對應點的x軸坐标,而是圖檔中對應點的y坐标(也就是程式設計中的pic.rows那行)。x2同理。

 3. 如果所畫圖像是多通道的,比如說image圖像的通道數時n,則使用Mat::at(x, y)時,其x的範圍依舊是0到image的height,而y的取值範圍則是0到image的width乘以n,因為這個時候是有n個通道,是以每個像素需要占有n列。但是如果在同樣的情況下,使用Mat::at(point)來通路的話,則這時候可以不用考慮通道的個數,因為你要指派給擷取Mat::at(point)的值時,都不是一個數字,而是一個對應的n維向量。

 4. 多通道圖像在使用minMaxLoc()函數時不能給出其最大最小值坐标的,因為每個像素點其實有多個坐标,是以是不會給出的。是以在程式設計時,這2個位置應該給NULL。

  5 多通道的圖像可以直接指派,不必每個通道指派。但是要注意其類型是Vec3b,如果寫成uchar,最後的copy圖像隻會顯示源圖像的1/3

char *tempPath="0.jpg";
    Mat src=imread(tempPath);
    Mat copy=Mat::zeros(src.rows,src.cols,src.type());
    for (int nrows=0;nrows<src.rows;nrows++)
    {
        for (int ncols=0;ncols<src.cols;ncols++)
        {
            copy.at<Vec3b>(nrows,ncols)=src.at<Vec3b>(nrows,ncols);

        }
    }
           
Mat src=imread("image/color.jpg");
    imshow("a",src);
    int i,j;
    int cPointR,cPointG,cPointB,cPoint;//currentPoint;
    for(i=1;i<src.rows;i++)
        for(j=1;j<src.cols;j++)
        {
            cPointB=src.at<Vec3b>(i,j)[0];
            cPointG=src.at<Vec3b>(i,j)[1];
            cPointR=src.at<Vec3b>(i,j)[2];
            if(cPointB>100&cPointR<100&cPointG<100)
                {
                    src.at<Vec3b>(i,j)[0]=0;  //單通道是uchar,沒有[0][1][2]
                    src.at<Vec3b>(i,j)[1]=0;
                    src.at<Vec3b>(i,j)[2]=0;
            }
            
        }
    imshow("da",src);
           

 注意每個點的像素灰階值cPointR,cPointG,cPointB,cPoint的資料類型是int,在單通道圖内由于讀取像素灰階值的代碼是img.at<uchar>(nrows,ncols),是以特别容易把資料類型記成unsigned char型

 ============================================================

【轉】VC++讀取圖像RGB值(未試驗)

opencv圖像像素值讀取
#include <iostream>
#include <fstream>
#include <string>
#include <windows.h>
#include <gdiplus.h>
#pragma comment(lib, "gdiplus.lib")

using namespace std;
using namespace Gdiplus;

int main() 
{
    GdiplusStartupInput gdiplusstartupinput;
    ULONG_PTR gdiplustoken;
    GdiplusStartup(&gdiplustoken, &gdiplusstartupinput, NULL);

    wstring infilename(L"1.jpg");
    string outfilename("color.txt");

    Bitmap* bmp = new Bitmap(infilename.c_str());
    UINT height = bmp->GetHeight();
    UINT width  = bmp->GetWidth();
    cout << "width " << width << ", height " << height << endl;

    Color color;
    ofstream fout(outfilename.c_str());

    for (UINT y = 0; y < height; y++)
    for (UINT x = 0; x < width ; x++)
        {
            bmp->GetPixel(x, y, &color);
            fout << x << "," << y << ";"
                 << (int)color.GetRed()   << ","
                 << (int)color.GetGreen() << ","
                 << (int)color.GetBlue()  << endl;
    }

    fout.close();

    delete bmp;
    GdiplusShutdown(gdiplustoken);
    return 0;
}      
opencv圖像像素值讀取

關于資料的儲存:(轉)

Mat_<uchar>對應的是CV_8U,Mat_<char>對應的是CV_8S,Mat_<int>對應的是CV_32S,Mat_<float>對應的是CV_32F,Mat_<double>對應的是CV_64F,對應的資料深度如下:

• CV_8U - 8-bit unsigned integers ( 0..255 )

• CV_8S - 8-bit signed integers ( -128..127 )

• CV_16U - 16-bit unsigned integers ( 0..65535 )

• CV_16S - 16-bit signed integers ( -32768..32767 )

• CV_32S - 32-bit signed integers ( -2147483648..2147483647 )

• CV_32F - 32-bit floating-point numbers ( -FLT_MAX..FLT_MAX, INF, NAN )

• CV_64F - 64-bit floating-point numbers ( -DBL_MAX..DBL_MAX, INF, NAN )

這裡還需要注意一個問題,很多OpenCV的函數支援的資料深度隻有8位和32位的,是以要少使用CV_64F,但是vs的編譯器又會把float資料自動變成double型,有些不太爽。