Rubiks Cube Farberkennung
-
Hallo liebe Mitglieder,
ich bin ganz neu in diesen Forum und bin in Sachen Programmieren noch ein blutiger Anfänger.
Ich habe mir vorgenommen eine Farberkennung mit openCV für den Zauberwürfel zu programmieren, jedoch habe ich Probleme einen Code dafür zu schreiben.
Im Prinzip habe ich eine Kamera in einer Box eingebaut die eine viereckige Öfnnung hat über die der Rubiks Cube gelegt wird. Das Innere der Box ist beleuchtet um immer die gleichen Lichtverhältnisse sicherzustellen. Da die Position fix ist hatte ich daran gedacht im Bild der Kamera 9 Quadrate festzulegen aus denen dann die Informationen gewonnen werden.
Bei Youtube habe ich auch Beispiele:https://i.ytimg.com/vi/p9BbvM2ADNE/hqdefault.jpg
https://i.ytimg.com/vi/p9BbvM2ADNE/hqdefault.jpg
Kennt sich jemand in OpenCV so gut aus das er mir zeigen könnte wir der Code aussehen muss? Ich habe vorallem Schwierigkeiten mit den OpenCV Befehlen umzugehen.
Also konkret wie ich die Vierecke zum Auswerten der Farben ins Bild bringe, wie ich danach den Durchschnitt der Farbanteile im jeweiligen Viereck bilde, und wie ich die einzelnen Farben danach in einen String schrieben kann.(Ich verwende Code::Blocks unter Linux, und OpenCV 3.1)
Vielen Dank,
Marty.
-
http://blog.ayoungprogrammer.com/2013/04/tutorial-detecting-multiple-rectangles.html/
dann warpPerspective http://docs.opencv.org/2.4/modules/imgproc/doc/geometric_transformations.html
von da ist es ja dann einfach / 3...
-
Geht aber sicher auch mit einem CvHaarClassifierCascade, nur dass dann eben die 9 Punkte erkannt werden müssen.
Dann einfach um die 9 erkannten Punkte die nächsten paar Pixel, das sollte ja reichen, ist ja nicht so, als wären die bunt...
-
Nur mal so'ne Idee: wie wäre es wenn du die Pixel in HSV umrechnest? H ist dabei nämlich der Farbton und S die Sättigung. Lichtverhältnisse (V) werden dann weniger relevant.
Zum Finden von Flächen einer Farbe könnte das vielleicht nützlich sein.
-
Ich habe es nun halbwegs hinbekommen . Vielen Dank für eure Hinweise!
#include "opencv2/imgproc/imgproc.hpp" #include "opencv2/core/core.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/opencv.hpp" #include "opencv/highgui.h" #include <iostream> #include <bits/stdc++.h> #include <cmath> using namespace cv; using namespace std; //helper function //finds camera settings void getCameraInfo(VideoCapture m_cam){ std::cout<<"CV_CAP_PROP_FRAME_WIDTH " << m_cam.get(CV_CAP_PROP_FRAME_WIDTH) << std::endl; std::cout<<"CV_CAP_PROP_FRAME_HEIGHT " << m_cam.get(CV_CAP_PROP_FRAME_HEIGHT) << std::endl; std::cout<<"CV_CAP_PROP_FPS " << m_cam.get(CV_CAP_PROP_FPS) << std::endl; std::cout<<"CV_CAP_PROP_EXPOSURE " << m_cam.get(CV_CAP_PROP_EXPOSURE) << std::endl; std::cout<<"CV_CAP_PROP_FORMAT " << m_cam.get(CV_CAP_PROP_FORMAT) << std::endl; //deafult CV_8UC3?! std::cout<<"CV_CAP_PROP_CONTRAST " << m_cam.get(CV_CAP_PROP_CONTRAST) << std::endl; std::cout<<"CV_CAP_PROP_BRIGHTNESS "<< m_cam.get(CV_CAP_PROP_BRIGHTNESS) << std::endl; std::cout<<"CV_CAP_PROP_SATURATION "<< m_cam.get(CV_CAP_PROP_SATURATION) << std::endl; std::cout<<"CV_CAP_PROP_HUE "<< m_cam.get(CV_CAP_PROP_HUE) << std::endl; std::cout<<"CV_CAP_PROP_POS_FRAMES "<< m_cam.get(CV_CAP_PROP_POS_FRAMES) << std::endl; std::cout<<"CV_CAP_PROP_FOURCC "<< m_cam.get(CV_CAP_PROP_FOURCC) << std::endl; int ex = static_cast<int>(m_cam.get(CV_CAP_PROP_FOURCC)); // Get Codec Type- Int form char EXT[] = {(char)(ex & 255) , (char)((ex & 0XFF00) >> 8),(char)((ex & 0XFF0000) >> 16),(char)((ex & 0XFF000000) >> 24), 0}; cout << "Input codec type: " << EXT << endl; } int findcolourhsv(float h,float s,float v) { float e=0.0000001; if((fabs(h-0)<e)||((-s+80)>=e)) return 1;//white if(((h-23)<=0)&&((h-5)>=0)) return 2;//orange if(((h-38)<=0)&&((h-27)>=0)) return 3;//yellow if(((h-75)<=0)&&((h-60)>=0)) return 4;//green if(((h-130)<=0)&&((h-80)>=0)) return 5;//blue //if((((h-179)<=0)&&((h-160)>=0))||(fabs(h-0)<5)) return 6;//red if((((h-60)<=0)&&((h-19)>=0))||((((h-179)<=0)&&((h-160)>=0))||(fabs(h-0)<5))) return 6;//red return -1; } struct c { unsigned char r, g, b; }; c colors[] = { {199, 225, 255}, // white {179, 100, 1}, // orange {195, 220, 2}, // yellow { 17, 140, 92}, // green { 2, 50, 210}, // blue {138, 30, 45} // red }; int main() { VideoCapture cap; cap.open(0); //adjust cam-number //getCameraInfo(cap); cap.set(CV_CAP_PROP_FRAME_WIDTH,320); cap.set(CV_CAP_PROP_FRAME_HEIGHT,240); cap.set(CV_CAP_PROP_GAIN,0.55); //adjust gain cap.set(CV_CAP_PROP_BRIGHTNESS,0.50); //capture.set(CV_CAP_PROP_SETTINGS,true); //cap.set(CV_CAP_PROP_EXPOSURE,0.17); //adjust exposure //cap.set(CV_CAP_PROP_CONTRAST,10); // capture.set(CV_CAP_PROP_HUE,2); //cap.set(CV_CAP_PROP_AUTOFOCUS,0); cap.set(CV_CAP_PROP_FOCUS,0.7); if (!cap.isOpened()) { return -1; } Mat frame; for (;;) { cap >> frame; if (frame.empty()) { return -1; } imshow("Original", frame); Mat cropedImage1= frame(Rect(65,30,200,200)); Mat cropedImage2; cvtColor(cropedImage1,cropedImage2,CV_BGR2HSV); int image_x = cropedImage2.cols; int image_y = cropedImage2.rows; float xr1 = 0.01; //0.3 float xr2 = 0.63; float yr1 = 0.01; //0.25 float yr2 = 0.63; for (int j = 0; j < 3; j++) for (int i = 0; i < 3; i++) { float cell_x = (xr2 - xr1) / 1.9;// 3.0 float cell_y = (yr2 - yr1) / 1.9;// 3.0 float buffer_x = cell_x * 0.19; //0.2 float buffer_y = cell_y * 0.19;//0.2 int x1 = (i * cell_x + xr1 + buffer_x) * image_x; int y1 = (j * cell_y + yr1 + buffer_y) * image_y; int x2 = ((i+1) * cell_x + xr1 - buffer_x) * image_x; int y2 = ((j+1) * cell_y + yr1- buffer_y) * image_y; Mat cropedPattern = cropedImage2(Rect(x1,y1,(x2-x1),(y2-y1))); Scalar mymean=mean(cropedPattern); int c=findcolourhsv(mymean.val[0],mymean.val[1],mymean.val[2]); switch(c){ case 1: cout<<"White"<<"\t"; break; case 2: cout<<"Orange"<<"\t"; break; case 3: cout<<"Yellow"<<"\t"; break; case 4: cout<<"Green"<<"\t"; break; case 5: cout<<"Blue"<<"\t"; break; case 6: cout<<"Red"<<"\t"; break; } rectangle( cropedImage1, Point( x1, y1 ), Point( x2, y2 ), Scalar( colors[c-1].b, colors[c-1].g, colors[c-1].r), -1, 8 ); imshow("Cube", cropedImage2); imshow("Cube 1", cropedImage1); } cout<<"\n"; waitKey(1); } return 0; }