2012-09-20 5 views
7

여기에 문제가 있습니다 : OpenCV v.2.4.2를 사용하여 그레이 스케일 이미지를로드합니다. 이제 예를 들어 위치 (0,0)의 픽셀 값을 알고 싶습니다. 시도 :OpenCV 행렬 값 표시

Mat image=imread("00001.jpg",1); 
cvtColor(image,image,CV_RGB2GRAY); 
int a=image.at<unsigned>(0,1); 
printf("%d ",a); 

이것은 실제로 작동하지 않습니다. 모든 데이터 형식 (CV_8U, CV_32S ...)으로 픽셀 값을 얻는 방법?

감사합니다 !!!

+0

(0,0) 대신 (0,1)을 사용하고 계십니까? – count0

답변

4

여기서 두 가지 실수를 저지르고 있습니다.

이미지를 읽는 동안 입력 인수로 1을 지정합니다. imread에서 설명한 것처럼이 함수는 세 가지 형식으로 이미지를 읽을 수 있습니다. CV_LOAD_IMAGE_GRAYSCALE (0) 강도와 같은 하나
CV_LOAD_IMAGE_COLOR을 (> 0) RGB 포맷의 이미지를로드하여 이미지를로드 (존재하는 경우 알파 채널 포함)

CV_LOAD_IMAGE_UNCHANGED (< 0)와 같이 이미지를로드 당신이 사용하는 경우 귀하의 케이스에 대한

다음 단계에서 두 번째 인수로

CV_LOAD_IMAGE_GRAYSCALE를 사용해야합니다 : image.at<unsigned>(0,1); CORR하지 않는 무엇이든 소망한다. 당신은 <unsigned>를 사용하지만 컴파일러는 "UNSIGNED? UNSIGNED what ???"이라고 말합니다.

올바른 방법은 CV_LOAD_IMAGE_COLOR 또는 CV_LOAD_IMAGE_GRAYSCALE과 같은 올바른 라벨을 사용하는 것입니다. 아래의 예에서는 이미지를 하나의 채널 (CV_LOAD_IMAGE_GRAYSCALE)으로 읽어들입니다.이 채널은 자동으로 그레이 스케일로 변환됩니다.

#include <cv.h> 
#include <highgui.h> 

#include <iostream> 

using namespace std; 
using namespace cv; 

int main() 
{ 
    Mat gImg = imread("img.png", CV_LOAD_IMAGE_GRAYSCALE); 

    uchar val; 
    val = gImg.at<uchar>(0,0); 

    cout << (int)val << endl; 

    imshow("showImg",gImg); 
    cvWaitKey(0); 

    return 1; 
} 
+0

좋아, 좋아,이 작품은,하지만 당신이 실제로 출력 무엇을 시도 했습니까? 제 경우에는 픽셀 (0,0)에 대해 -89를 얻습니다. 이미지가 8 비트 서명되지 않은 경우 어떻게 가능합니까? 다음으로 왜 uchar을 사용하는지 묻고 싶습니다. –

+0

물론 시도해 보았습니다. 왜 출력이 제대로 나오지 않는지 나는 모른다. 위의 설명에서 @ count0으로 설명하는 것과 동일한 이유로 UCHAR을 정확히 사용했습니다. 즉, 0에서 255 사이의 값을 나타낼 수 있습니다. – masad

+1

이렇게하면 imread를 사용할 수 없습니다. 두 번째 인수는 이미지 그레이 스케일, 3 채널 색상 또는 그대로 읽을 것인지에 따라 0,> 0 또는 <0 중 하나 인 플래그입니다. 유형을 정확히 지정할 수 없습니다. CV_8U == 0이기 때문에 특정 경우에만 실행됩니다. – Sassa

0

당신이 사용하는 어떤 종류의 더 나은 아이디어를 가지고 그것을 표현 무슨 짓을했는지 OpenCV의 발견을 시도 할 수 있습니다 :

cout << image.depth() << ", " << image.channels() << endl; 

는 또한 요소 액세스에 대한이 discussion을 확인합니다.

+0

글쎄, 깊이와 채널을 알고 있지만, 행렬이 CV_8UC1이되도록 평행 이미지 8 비트와 부호없는 정수를 알고 있다면 어떤 매개 변수를 Mat :: at로 전달해야합니까? 정확히 여기에 : image.at (0,1); –

+0

CV_8UC1은 8 비트 부호없는 단일 채널을 의미하므로 'unsigned char'는 0..255의 값을 나타냅니다. 부호없는 정수는 CV_16UC1이 될 0..65536의 값을 나타냅니다. – count0

0

우선,이 방법으로 픽셀 값을 가져 오는 일반적인 방법은 없습니다. at을 사용하려는 경우 항상 올바른 유형의 값을 지정해야한다는 의미입니다. 이 경우 이미지를 8 비트 부호없는 회색 음영 (1 채널)으로 변환하므로 a=image.at<uchar>(0,1);을 수행해야합니다.

OpenCV가 BGR을 채널 순서로 사용하므로 RGB2GRAY 대신 CV_BGR2GRAY를 사용해야합니다.

또한 처음부터 그레이 스케일로 이미지를 읽고 다시 uchar을 사용할 수

Mat image = imread("00001.jpg",0); // note the 0 flag 
int a=image.at<uchar>(0,1); 
printf("%d ",a); 
1

이 작업을 수행하는 쉬운 방법이있다.

매트는 Mat.data 원래 데이터 매트릭스를 가리키는 포인터를 제공 갖는다.

Mat img = imread("filename.jpg",CV_LOAD_IMAGE_COLOR); 
unsigned char *input = (unsigned char*)(img.data); 

int i,j,r,g,b; 
for(int i = 0;i < img.cols;i++){ 
    for(int j = 0;j < img.rows;j++){ 
     b = input[img.cols * j + i ] ; 
     g = input[img.cols * j + i + 1]; 
     r = input[img.cols * j + i + 2]; 
    } 
} 

그래서,이 컬러 화상에 대해이고, n 행의 와 제 m 열에의 화소 값을 얻으려면. 회색 음영 이미지의 경우

Mat img = imread("filename.jpg",CV_LOAD_IMAGE_COLOR); 
Mat g; 
cvtColor(img, g, CV_BGR2GRAY); 
unsigned char *input = (unsigned char*)(g.data); 

int i,j,r,g,b; 
for(int i = 0;i < img.cols;i++){ 
    for(int j = 0;j < img.rows;j++){ 
     g = input[img.cols * j + i]; 
    } 
} 

자세한 내용은 blogpost을 참조하십시오.