2017-03-04 5 views
0

Ich habe ein Bild, das throw verarbeitet wurde:OpenCV Mat Bilddatenstruktur

//UIImage to Mat 
cv::Mat originalMat = [self cvMatFromUIImage:inputImage]; 

//Grayscale 
cv::Mat grayMat; 
cv::cvtColor(originalMat, grayMat, CV_RGB2GRAY); 

//Blur 
cv::Mat gaussMat; 
cv::GaussianBlur(grayMat , gaussMat, cv::Size(9, 9), 2, 2); 

//Threshold 
cv::threshold(grayMat,tMat,100,255,cv::THRESH_BINARY); 

als ich (berechnen Menge der weißen und schwarzen Punkte), die Linie BELOWS analysieren möchten. Zum Beispiel: Ich habe ein Bild 100x120px und ich möchte Zeilen überprüfen, wo x = 5 und y = from 0 to 119; und umgekehrt x = 0..99; y = 5;

so erwarte ich, dass enthält x - Mat.cols und y - Mat.rows aber sieht es Daten auf eine andere Weise speichert. zum Beispiel habe ich versucht, Pixel, Farbe zu ändern, die auf Linien BELOWS aber nicht 2 Zeilen bekommen haben:

for(int x = 0; x < tMat.cols; x++){ 
    tMat.at<cv::Vec4b>(5,x)[0] = 100; 
} 

for(int y = 0; y < tMat.rows; y++){ 
    tMat.at<cv::Vec4b>(y,5)[0] = 100; 
} 
return [self UIImageFromCVMat:tMat]; 

Ergebnis für Weiß-Bild:

enter image description here

warum ich did't 2 erhalten Linien? Ist es möglich, Linien in Mat direkt zu zeichnen? Was passiert, wenn ich die Linie überprüfe, die über y = kx + b berechnet?

Antwort

3

Sie greifen falsch auf die Pixelwerte zu. Sie sind mit dem Bild arbeiten, die nur einen Kanal hat, das ist, warum Sie Pixelwerte wie folgt zugreifen sollte:

Typ ist definiert durch zwei Eigenschaften
for (int x = 0; x < tMat.cols; x++){ 
    tMat.at<unsigned char>(5, x) = 100; 
} 

for (int y = 0; y < tMat.rows; y++){ 
    tMat.at<unsigned char>(y, 5) = 100; 
} 

Das Mat Elements - der Anzahl von Kanälen und der zugrunde liegenden Art der Daten. Wenn Sie die Bedeutung dieser Begriffe nicht kennen, empfehlen wir dringend, dass Sie die Dokumentation zu den Methoden cv::Mat::type(), cv::Mat::channels() und cv::Mat::depth() lesen.

Zwei weitere Beispiele:

mat.at<float>(x, y) = 1.0f; // if mat type is CV_32FC1 
mat.at<cv::Vec3b>(x, y) = Vec3b(1, 2, 3); // if mat type is CV_8UC3 
2

Wahrscheinlich ein Problem mit Ihren Mat-Datentypen. Die Ausgabe des Schwellenwerts ist ein Einzelkanalbild mit 8 Bit oder 32 Bit (http://docs.opencv.org/2.4/modules/imgproc/doc/miscellaneous_transformations.html?highlight=threshold#threshold). Daher sollten Sie wahrscheinlich keine Werte mit Mat.at<Vec4b>[0] einstellen.

Hier ist eine Funktion, um den Typ Ihrer Matrix zurückzugeben. Die Nutzung erfolgt im auskommentierten Teil. Kopiert von How to find out what type of a Mat object is with Mat::type() in OpenCV.

std::string type2str(int type){ 
//string ty = type2str(comparisonResult.type()); 
//printf("Matrix: %s %dx%d \n", ty.c_str(), comparisonResult.cols, comparisonResult.rows); 

string r; 

uchar depth = type & CV_MAT_DEPTH_MASK; 
uchar chans = 1 + (type >> CV_CN_SHIFT); 

switch (depth) { 
case CV_8U: r = "8U"; break; 
case CV_8S: r = "8S"; break; 
case CV_16U: r = "16U"; break; 
case CV_16S: r = "16S"; break; 
case CV_32S: r = "32S"; break; 
case CV_32F: r = "32F"; break; 
case CV_64F: r = "64F"; break; 
default:  r = "User"; break; 
} 

r += "C"; 
r += (chans+'0'); 

return r;}