Colour Colour::hsvMod(glm::ivec3 _hsvDelta){ glm::ivec3 hsv = rgbToHsv(*this) + _hsvDelta; hsv.x = glm::mod((float)hsv.x, 360.f); hsv.y = glm::min(100, glm::max(0, hsv.y)); hsv.z = glm::min(100, glm::max(0, hsv.z)); return Colour(hsvToRgb(hsv)); }
Intensity StudentPreProcessing::getPixelIntensity(const RGB & pixel) const { const IntensityChannel channelz[] = { IntensityChannel::Red, IntensityChannel::Green, IntensityChannel::Blue, IntensityChannel::Cyan, IntensityChannel::Magenta, IntensityChannel::Yellow, IntensityChannel::Black, IntensityChannel::Hue, IntensityChannel::Saturation, IntensityChannel::Value, }; int total = 0; int nChannels = 0; float c, m, y, k; float h, s, v; rgbToCmyk(pixel.r, pixel.g, pixel.b, c, m, y, k); rgbToHsv(pixel.r, pixel.g, pixel.b, h, s, v); for (const auto & channel : channelz) { switch (channel & channels) { case IntensityChannel::Red: total += pixel.r; break; case IntensityChannel::Green: total += pixel.g; break; case IntensityChannel::Blue: total += pixel.b; break; case IntensityChannel::Cyan: total += static_cast<int>(c * 255); break; case IntensityChannel::Magenta: total += static_cast<int>(m * 255); break; case IntensityChannel::Yellow: total += static_cast<int>(y * 255); break; case IntensityChannel::Black: total += static_cast<int>(k * 255); break; case IntensityChannel::Hue: total += static_cast<int>((h / 360.0f) * 255);break; case IntensityChannel::Saturation: total += static_cast<int>(s * 255); break; case IntensityChannel::Value: total += static_cast<int>(v * 255); break; default: continue; } ++nChannels; } if (nChannels) { return static_cast<Intensity>(total / nChannels); } //std::cerr << "No channels were specified." << std::endl; return static_cast<Intensity>(0); }
vec3 ColorAT<T>::get( ColorModel cm ) const { switch( cm ) { case CM_HSV: return rgbToHsv( Colorf( r, g, b ) ); break; case CM_RGB: return vec3( CHANTRAIT<float>::convert( r ), CHANTRAIT<float>::convert( g ), CHANTRAIT<float>::convert( b ) ); break; default: throw ImageIoExceptionIllegalColorModel(); } }
//pixel classification float CRecognition::evaluatePixel3(unsigned char* a) { float result = 0; unsigned int h; unsigned char s,v; rgbToHsv(a[0],a[1],a[2],&h,&s,&v); if (v > 50 && s > 50){ result = result + pow((int)h-(int)learnedHue,2); result = result + pow((int)s-(int)learnedSaturation,2)/4; result = result + pow((int)v-(int)learnedValue,2)/16; }else{ return 0; } result = sqrt(result); if (result > tolerance) result = 0; else result = 1; return result; }
//learns a given pixel void CRecognition::learnPixel(unsigned char* a) { //saves the pixel for (int i =0;i<3;i++) learned[i] = a[i]; //transforms it to HSV rgbToHsv(learned[0],learned[1],learned[2],&learnedHue,&learnedSaturation,&learnedValue); //creates an indexing table unsigned char u[3]; for (u[0]=0;u[0]<252;u[0]=u[0]+4){ for (u[1] = 0;u[1]<252;u[1]=u[1]+4){ for (u[2] = 0;u[2]<252;u[2]=u[2]+4){ int i = ((u[0]/4)*64+u[1]/4)*64+u[2]/4; colorArray[i] = evaluatePixel3(u); } } } // fprintf(stdout,"Learned RGB: %i %i %i, HSV: %i %i %i\n", // learned[0],learned[1],learned[2],learnedHue,learnedSaturation,learnedValue); }
void Hsv::rgbToHsv(VectorRgba const & rgb, Vector & hsv ) { rgbToHsv(rgb.r, rgb.g, rgb.b, hsv.x, hsv.y, hsv.z); }
int main() { //inicialização camera *cam = camera_inicializa(0); if(!cam) erro("erro na inicializacao da camera\n"); int largura = cam->largura; int altura = cam->altura; if(!al_init()) erro("erro na inicializacao do allegro\n"); if(!al_init_image_addon()) erro("erro na inicializacao do adicional de imagem\n"); if(!al_init_primitives_addon()) erro("erro na inicializacao do adicional de primitivas\n"); ALLEGRO_TIMER *timer = al_create_timer(1.0 / FPS); if(!timer) erro("erro na criacao do relogio\n"); ALLEGRO_DISPLAY *display = al_create_display(largura, altura); if(!display) erro("erro na criacao da janela\n"); ALLEGRO_EVENT_QUEUE *queue = al_create_event_queue(); if(!queue) erro("erro na criacao da fila\n"); al_register_event_source(queue, al_get_timer_event_source(timer)); al_register_event_source(queue, al_get_display_event_source(display)); al_start_timer(timer); /**********/ unsigned char ***matriz = camera_aloca_matriz(cam); int ***background = alocaHsvMatriz(cam->largura, cam->altura); fila *f = aloca(); //cor para desenhar o círculo ALLEGRO_COLOR cor = al_map_rgb_f(0, 0, 1); ALLEGRO_BITMAP *buffer = al_get_backbuffer(display); //tela exibindo img normal ALLEGRO_BITMAP *esquerda = al_create_sub_bitmap(buffer, 0, 0, largura, altura); //tela mostrando como o computador enxerga //ALLEGRO_BITMAP *direita = al_create_sub_bitmap(buffer, largura/2, 0, largura/2, altura/2); ALLEGRO_BITMAP *silhueta = al_create_bitmap(largura, altura); /**********/ srand(time(NULL)); int desenhar = 0; int terminar = 0; int cycle = 0; int hitx = rand() % (largura); int hity = rand() % (altura); int x, y; float cyr, cxr, cnr, lastCx, lastCy; int r, g, b, r2, g2, b2; int h, s, v, h2, s2, v2; int fh, fs, fv; int dh, ds, dv; int tempH; int token; double value; int dist; al_rest(1); for(y = 0; y < altura; y++) for(x = 0; x < largura; x++){ rgbToHsv(cam->quadro[y][x][0], cam->quadro[y][x][1], cam->quadro[y][x][2], &background[y][x][0], &background[y][x][1], &background[y][x][2]); if(background[y][x][0] > 180){ background[y][x][0] -= 360; background[y][x][0] = -background[y][x][0]; } } al_rest(1); for(y = 0; y < altura; y++) for(x = 0; x < largura; x++){ rgbToHsv(cam->quadro[y][x][0], cam->quadro[y][x][1], cam->quadro[y][x][2], &fh, &fs, &fv); if(fh > 180){ fh -= 360; fh = -fh; } background[y][x][0] += fh; background[y][x][0] /=2; background[y][x][1] += fs; background[y][x][1] /=2; background[y][x][2] += fv; background[y][x][2] /=2; } //gameloop while(1) { ALLEGRO_EVENT event; al_wait_for_event(queue, &event); switch(event.type) { case ALLEGRO_EVENT_TIMER: desenhar = 1; break; case ALLEGRO_EVENT_DISPLAY_CLOSE: terminar = 1; break; default: printf("evento desconhecido\n"); } if(terminar) break; //interpretar img e realizar transformações printf("%d\n", al_is_event_queue_empty(queue)); if(desenhar && al_is_event_queue_empty(queue)) { desenhar = 0; camera_atualiza(cam); /**********/ int bx, by, bn; cyr = 0; cxr = 0; cnr = 0; for(y = 0; y < altura; y++){ for(x = 0; x < largura; x++){ //Espada r = cam->quadro[y][x][0]; g = cam->quadro[y][x][1]; b = cam->quadro[y][x][2]; rgbToHsv(r, g, b, &h, &s, &v); if(h < 15 || h > 345) if(s > 75 && v > 75){ cyr += y; cxr += x; cnr++; } //Silhueta (REFINAR!!!) if(h > 180) tempH = -(h - 360); else tempH = h; dh = tempH - background[y][x][0]; if(dh < 0) dh = -dh; ds = s - background[y][x][1]; if(ds < 0) ds = -ds; dv = v - background[y][x][2]; if(dv < 0) dv = -dv; //dh > 15 && ds > 10 para tirar a interfencia de iluminacao, mas gera mtuiro ruido //ds > 25 é o mais preciso, mas sofre de interferencia de iluminacao if(dv > 25){ //valores para teste! matriz[y][x][0] = 37; matriz[y][x][1] = 50; matriz[y][x][2] = 248; } else{ matriz[y][x][0] = 0; matriz[y][x][1] = 0; matriz[y][x][2] = 0; } //Escudo if(h < 135 && h > 105 && s > 50 && v > 75){ by += y; bx += x; bn++; matriz[y][x][0] = 0; matriz[y][x][1] = 255; matriz[y][x][2] = 0; } } } /*for(y = 1; y < altura-1; y++) for(x = 1; x < largura-1; x++){ token = 4; if(255 != matriz[y+1][x][0]) token--; if(255 != matriz[y-1][x][0]) token--; if(255 != matriz[y][x+1][0]) token--; if(255 != matriz[y][x-1][0]) token--; if(token == 0){ matriz[y][x][0] = 0; matriz[y][x][1] = 0; matriz[y][x][2] = 0; }*/ cycle++; if(cycle > 50 && bn > 0){ value = (pow(hitx - (bx / 2 /bn), 2) + pow(hity - (by / 2 / bn), 2)); dist = sqrt(value) - 7; if(dist < 100 && dist > -100 && bn > 0) printf("block!\n"); else{ if(matriz[hity][hitx][0] == 255) printf("hit\n"); else printf("miss\n"); } cycle = 0; hitx = rand() % (largura/2); hity = rand() % (altura/2); } /**********/ camera_copia(cam, cam->quadro, esquerda); //Copia img editada na img direita camera_copia(cam, matriz, silhueta); //cor para teste! al_convert_mask_to_alpha(silhueta, al_map_rgb(37, 50, 248)); al_draw_bitmap(silhueta, 0, 0, 0); /**********/ if(bn > 0) al_draw_circle(bx / bn, by / bn, 100, al_map_rgb(0, 0, 255), 1); if(cycle >= 40){ if(cycle < 48){ al_draw_circle(hitx, hity, 15, al_map_rgb(0, 0, 255), 30); al_draw_circle(hitx + largura, hity, 6, al_map_rgb(0, 0, 255), 3); } else al_draw_circle(hitx, hity, 15, al_map_rgb(255, 0, 0), 30); } if(cnr > 10){ lastCx = cxr / cnr; lastCy = cyr / cnr; al_draw_circle(lastCx, lastCy, 100, al_map_rgb(255, 0, 0), 1); insere(f, lastCx, lastCy); } else insere(f, lastCx, lastCy); if(f->count > 10) retira(f); drawAtk(f); al_flip_display(); } } /**********/ libera(f); al_destroy_bitmap(silhueta); al_destroy_bitmap(esquerda); camera_libera_matriz(cam, matriz); liberaHsvMatriz(background, cam->largura, cam->altura); /**********/ al_stop_timer(timer); al_unregister_event_source(queue, al_get_display_event_source(display)); al_unregister_event_source(queue, al_get_timer_event_source(timer)); al_destroy_event_queue(queue); al_destroy_display(display); al_destroy_timer(timer); al_shutdown_primitives_addon(); al_shutdown_image_addon(); al_uninstall_system(); camera_finaliza(cam); return EXIT_SUCCESS; }
/** Returns a pointer to a new image, based on 'surface' but with changed hue. Changing the hue means to "rotate" the color spectrum. You can read more about the HSV color model on the Internet. This method is used to change the color of a sprite (e.g. a car or another object). I suggest to make the basic images in a red color-spectrum and create all other colors from it. For examples, please visit the Trophy homepage developer corner (http://trophy.sourceforge.net) \param hue Changing of hue: 0-360 \param saturation Changing of saturation: -100...100 \param value Changing of value (Color intensity): -100...100 */ CL_PixelBuffer CAImageManipulation::changeHSV( CL_PixelBuffer pixBufOriginal, int hue, int saturation, int value ) { CL_PixelBuffer pixbuf(pixBufOriginal.get_width(), pixBufOriginal.get_height(), pixBufOriginal.get_format()); pixBufOriginal.convert(pixbuf); CL_TextureFormat pf = pixbuf.get_format(); // Check that we handle this pixel format if(pf != CL_TextureFormat::cl_rgba8 && pf != CL_TextureFormat::cl_rgb8 && pf != CL_TextureFormat::cl_rgba4 ) { std::cout << "Unknow pixel format !" << pf << std::endl; return pixBufOriginal.copy(); } // Calc size in bytes: // int bpp = pixBufOriginal.get_bytes_per_pixel(); int size = pixbuf.get_width() * pixbuf.get_height() * bpp; pixbuf.lock(CL_BufferAccess::cl_access_read_write); unsigned char *data = (unsigned char*)pixbuf.get_data(); // Change hue: // int r, g, b, a(0); int h, s, v; for(int i=0; i<size; i+=bpp ) { if(pf == CL_TextureFormat::cl_rgba8) { a = data[i]; b = data[i+1]; g = data[i+2]; r = data[i+3]; } else if (pf == CL_TextureFormat::cl_rgb8) { std::cout << "TextureFormat : rgb888\n"; b = data[i]; g = data[i+1]; r = data[i+2]; } else if (pf == CL_TextureFormat::cl_rgba4) { std::cout << "TextureFormat : rgba4444\n"; r = data[i] && 0x0F; g = (data[i] && 0xF0) >> 4; b = data[i+1] && 0x0F; a = (data[i+1] && 0xF0) >> 4; } if( a!=0 && (r!=g || r!=b || g!=b) ) { rgbToHsv( r, g, b, &h, &s, &v ); h += hue; s += saturation; v += value; if( h > 360 ) h -= 360; if( s > 255 ) s = 255; if( v > 255 ) v = 255; if( h < 0 ) h += 360; if( s < 0 ) s = 0; if( v < 0 ) v = 0; hsvToRgb( h, s, v, &r, &g, &b ); if(pf == CL_TextureFormat::cl_rgba8) { data[i] = a; data[i+1] = b; data[i+2] = g; data[i+3] = r; } else if (pf == CL_TextureFormat::cl_rgb8) { data[i] = b; data[i+1] = g; data[i+2] = r; } else if (pf == CL_TextureFormat::cl_rgba4) { data[i] = r + (g << 4); data[i+1] = b + (a << 4); } } }