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.





  • 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;
    }
    

Log in to reply