/// Convert image to gray level Image Image::gray() const { if(channels() == 1) return *this; assert(channels() == 3); Image out(w,h); const float* in = tab; for(int y=0; y<h; y++) for(int x=0; x<w; x++, in+=3) out(x,y) = rgb_to_gray(in[0], in[1], in[2]); return out; }
static int mp750_fill_buffer (pixma_t * s, pixma_imagebuf_t * ib) { mp750_t *mp = (mp750_t *) s->subdriver; int error; uint8_t info; unsigned block_size, bytes_received, n; int shift[3], base_shift; int c; c = ((is_ccd_grayscale (s)) ? 3 : s->param->channels) * s->param->depth / 8; /* single-byte or double-byte data */ if (mp->state == state_warmup) { int tmo = 60; query_status (s); check_status (s); /*SIM*/ while (!is_calibrated (s) && --tmo >= 0) { if (s->cancel) return PIXMA_ECANCELED; if (handle_interrupt (s, 1000) > 0) { block_size = 0; error = request_image_block (s, &block_size, &info); /*SIM*/ if (error < 0) return error; } } if (tmo < 0) { PDBG (pixma_dbg (1, "WARNING: Timed out waiting for calibration\n")); return PIXMA_ETIMEDOUT; } pixma_sleep (100000); query_status (s); if (is_warming_up (s) || !is_calibrated (s)) { PDBG (pixma_dbg (1, "WARNING: Wrong status: wup=%d cal=%d\n", is_warming_up (s), is_calibrated (s))); return PIXMA_EPROTO; } block_size = 0; request_image_block (s, &block_size, &info); /*SIM*/ mp->state = state_scanning; mp->last_block = 0; } /* TODO: Move to other place, values are constant. */ base_shift = calc_component_shifting (s) * mp->line_size; if (s->param->source == PIXMA_SOURCE_ADF) { shift[0] = 0; shift[1] = -base_shift; shift[2] = -2 * base_shift; } else { shift[0] = -2 * base_shift; shift[1] = -base_shift; shift[2] = 0; } do { if (mp->last_block_size > 0) { block_size = mp->imgbuf_len - mp->last_block_size; memcpy (mp->img, mp->img + mp->last_block_size, block_size); } do { if (s->cancel) return PIXMA_ECANCELED; if (mp->last_block) { /* end of image */ info = mp->last_block; if (info != 0x38) { query_status (s); /*SIM*/ while ((info & 0x28) != 0x28) { pixma_sleep (10000); error = request_image_block2 (s, &info); if (s->cancel) return PIXMA_ECANCELED; /* FIXME: Is it safe to cancel here? */ if (error < 0) return error; } } mp->needs_abort = (info != 0x38); mp->last_block = info; mp->state = state_finished; return 0; } check_status (s); /*SIM*/ while (handle_interrupt (s, 1) > 0); /*SIM*/ block_size = IMAGE_BLOCK_SIZE; error = request_image_block (s, &block_size, &info); if (error < 0) { if (error == PIXMA_ECANCELED) read_error_info (s, NULL, 0); return error; } mp->last_block = info; if ((info & ~0x38) != 0) { PDBG (pixma_dbg (1, "WARNING: Unknown info byte %x\n", info)); } if (block_size == 0) { /* no image data at this moment. */ pixma_sleep (10000); } } while (block_size == 0); error = read_image_block (s, mp->rawimg + mp->rawimg_left); if (error < 0) { mp->state = state_transfering; return error; } bytes_received = error; PASSERT (bytes_received == block_size); /* TODO: simplify! */ mp->rawimg_left += bytes_received; n = mp->rawimg_left / 3; /* n = number of pixels in the buffer? */ /* Color to Grayscale converion for CCD sensor */ if (is_ccd_grayscale (s)) { shift_rgb (mp->rawimg, n, shift[0], shift[1], shift[2], mp->stripe_shift, mp->line_size, mp->imgcol + mp->imgbuf_ofs); /* dst: img, src: imgcol */ rgb_to_gray (mp->img, mp->imgcol, n, c); /* cropping occurs later? */ PDBG (pixma_dbg (4, "*fill_buffer: did grayscale conversion \n")); } /* Color image processing */ else { shift_rgb (mp->rawimg, n, shift[0], shift[1], shift[2], mp->stripe_shift, mp->line_size, mp->img + mp->imgbuf_ofs); PDBG (pixma_dbg (4, "*fill_buffer: no grayscale conversion---keep color \n")); } /* entering remaining unprocessed bytes after last complete pixel into mp->rawimg buffer -- no influence on mp->img */ n *= 3; mp->shifted_bytes += n; mp->rawimg_left -= n; /* rawimg_left = 0, 1 or 2 bytes left in the buffer. */ mp->last_block_size = n; memcpy (mp->rawimg, mp->rawimg + n, mp->rawimg_left); } while (mp->shifted_bytes <= 0); if ((unsigned) mp->shifted_bytes < mp->last_block_size) { if (is_ccd_grayscale (s)) ib->rptr = mp->img + mp->last_block_size/3 - mp->shifted_bytes/3; /* testing---works OK */ else ib->rptr = mp->img + mp->last_block_size - mp->shifted_bytes; } else ib->rptr = mp->img; if (is_ccd_grayscale (s)) ib->rend = mp->img + mp->last_block_size/3; /* testing---works OK */ else ib->rend = mp->img + mp->last_block_size; return ib->rend - ib->rptr; }
/** Carga los ficheros de clasificacion automatica de estados y clases y clasifica las celulas de la imagen cuya ruta corresponde con la pasada por parametro. @param ruta, string de la ruta de la imagen a analizar. @param listCell, objeto ListadoCeulas que contiene todas las celulas de la imagen a analizar. */ void Clasificador::clasificarCelulas(string ruta, ListadoCelulas &listCell) { struct svm_model *svmEst, *svmCl; float media_est[N_ENTRADAS], desv_est[N_ENTRADAS]; float media_cl[N_ENTRADAS], desv_cl[N_ENTRADAS]; int y1, y2; int numCelulas, numPuntos; vector <int> *cx, *cy; Image *img, *img_grey, *img_bin; img = read_img ( ruta.c_str() ); img_grey = rgb_to_gray (img); numCelulas = listCell.getNumCelulas(); //Obtenemos path de los ficheros de clasificacion const char *f_svm_Est = fichClasificEst.c_str(); const char *f_med_desv_Est = fichMediaDesviaEst.c_str(); const char *f_svm_Cl = fichClasificCl.c_str(); const char *f_med_desv_Cl = fichMediaDesviaCl.c_str(); //Creamos los svm svmEst = crea_svm(f_svm_Est, f_med_desv_Est, media_est, desv_est); svmCl = crea_svm(f_svm_Cl, f_med_desv_Cl, media_cl, desv_cl); for(int i = 0; i < numCelulas; i++) { PointList *puntos; if(listCell.getCelula(i)->getEstadoCelula() != "outimage" && listCell.getCelula(i)->getClaseCelula() != "outimage") { cx = listCell.getCelula(i)->getBordeCellX(); cy = listCell.getCelula(i)->getBordeCellY(); numPuntos = cx->size(); puntos = alloc_point_list(numPuntos); //Convertimos puntos for(int j = 0; j < numPuntos; j++) { puntos->point[j] = alloc_point((*cy)[j], (*cx)[j]); } puntos->type = GEN_VALID; img_bin=computeBinImage ( puntos, get_num_rows ( img_grey ) , get_num_cols (img_grey)); // double* resul = texture_features_haralick(img, puntos, 1, 1); double * resul = texture_features_glrls_grey ( img_grey, img_bin, puntos, 1000, 0); float resul2[N_ENTRADAS], resul3[N_ENTRADAS]; for(unsigned int z = 0; z < N_ENTRADAS; z++) { resul2[z] = (float)resul[z]; resul3[z] = (float)resul[z]; } //Salida clasificador clases y1 = saida_svm(svmCl, resul2, media_cl, desv_cl); switch(y1) { case 0: listCell.getCelula(i)->setClaseCelula("cn"); break; case 1: listCell.getCelula(i)->setClaseCelula("sn"); break; } //Salida clasificador estados y2 = saida_svm(svmEst, resul3, media_est, desv_est); switch (y2) { case 0: listCell.getCelula(i)->setEstadoCelula("ac"); break; case 1: listCell.getCelula(i)->setEstadoCelula("hid"); break; case 2: listCell.getCelula(i)->setEstadoCelula("vit");// vitelinas o atresicas break; } free_point_list ( puntos ); free ( puntos->point ); free ( puntos ); // delete puntos; free ( resul ); } } destrue_svm(svmCl); destrue_svm(svmEst); free_img ( img ); free ( img ); free_img ( img_grey ); free ( img_grey ); }
/** Realiza la deteccion de todas las celulas de la imagen de forma automatica. */ bool DeteccionAut::deteccionBordesNoSupervisado() { // Maximun number of objects in the image int NUM_CELLS (10000 ); // Maximun roundness of interested objects in the image for unsupervised algorithm double MAX_ROUND ( 1.4 ); int i, l; int nout; PointList **out; if(diamMax != 0) { MAX_DIAMETER = diamMax / calibracion; } else { MAX_DIAMETER = MAX_DIAMETER / calibracion; } if(diamMin != 0) { MIN_DIAMETER = diamMin / calibracion; } else { MIN_DIAMETER = MIN_DIAMETER / calibracion; } // Read the input image img = read_img ( ruta.c_str() ); if ( !is_rgb_img ( img ) || (img == NULL)) { fprintf ( stderr, "Input image ( %s ) must be color image !", ruta.c_str() ); return false; } /********************************Reloj**************************************/ // comienzo = clock(); /***************************************************************************/ /***************************************************************************/ string mensaje, titulo; //mensaje = "Se va a proceder al cálculo de los bordes de los ovocitos, el proceso durara aproximadamente 1 minuto durante el cual la aplicación quedara bloqueada, ¿Esta seguro de continuar?"; mensaje = "The automatic oocyte edge detection is going to be performed. The application will be unaccesible during this process. Are you sure that you want to continue?"; //titulo = "Cálculo automatico de bordes de los ovocitos"; titulo = "Oocyte edge detection"; if(Dialogos::dialogoConfirmacion(mensaje, titulo)) { //DialogoBarraProgres dProgres("Detectando Bordes"); DialogoBarraProgres dProgres("Oocyte edge detection"); dProgres.ejectuaDialogoProgreso(); dProgres.setEstadoBarraProgreso(0.1); dProgres.setPercentText(0.1); Utiles::actualizarInterfaz(); /***************************************************************************/ // Detect the edges in the input image num_rows=get_num_rows(img); num_cols=get_num_cols(img); /*Este dobre bucle que ven a continuacion e a aplicacion do filtro de Canny para distintos umbrais e suavizados (distintas escalas). O que obtemos e en contour (unha estrutura da libreria fourier.0.8 que almacena os bordes que teñen mais de MIN_LENGTH pixels) e en n_all o numero de borde. */ // Este paso e independente de que o algoritmo se aplique de forma supervisada ou non supervisada. //num_edges = 0; if(num_rows > MAX_ROWS_IMAGE || num_cols > MAX_COLS_IMAGE) { fprintf(stderr, "Error: image of size %i x %i too large (max. size= %i x %i): border detection aborted\n", num_rows, num_cols, MAX_ROWS_IMAGE, MAX_COLS_IMAGE); Dialogos::dialogoError("Image too large for border detection", "Error"); return false; } img_grey=rgb_to_gray(img); // Aplicando o filtro de canny multiescalar contour=detect_edge_multiscalar_canny ( img_grey, &num_edges, MIN_DIAMETER, NUM_CELLS); if ( IS_NULL( contour)) { printf ( "Invalid point list objects !"); } // printf("Tempo transcurrido: %f bordes= %d \n", stop_timer ( start_time), num_edges) ; /**********************************fase 1****************************/ /* final = clock(); cout<<"Tiempo fase 1 "<<(final - comienzo)/(double) CLOCKS_PER_SEC<<endl; comienzo = clock();*/ dProgres.setEstadoBarraProgreso(0.5); dProgres.setPercentText(0.5); Utiles::actualizarInterfaz(); /**************************************************************************/ // A partir de aqui fanse calculos para analizar os bordes que hai en contour e asi mostrar so os que cremos que son bordes de govocitos maduros. //utilizando funcion aplico a deteccion non supervisada out=nonSuperviseDetection(contour, num_edges, num_cols, num_rows, MIN_DIAMETER, MAX_DIAMETER, MAX_ROUND, &nout); /**********************************Reloj fase 2****************************/ /* final = clock(); cout<<"Tiempo fase 2 "<<(final - comienzo)/(double) CLOCKS_PER_SEC<<endl; comienzo = clock();*/ dProgres.setEstadoBarraProgreso(0.9); dProgres.setPercentText(0.9); Utiles::actualizarInterfaz(); /**************************************************************************/ for ( l = 0; l <nout; l++) { /************************Pintado govocitos*************************/ PointList *p = out[l]; /*Guardamos los puntos en un objeto celula y lo añadimos al objeto de listado de celulas*/ pasoCoordSistemaGovocitos(p); /*******************************************************************/ } for(i=0; i<nout; i++) { free_point_list(out[i]); free(out[i]->point); free(out[i]); } free(out); free_img(img); free_img(img_grey); free(img); free(img_grey); /**********************************Reloj fase 3****************************/ /* final = clock(); cout<<"Tiempo fase 3 "<<(final - comienzo)/(double) CLOCKS_PER_SEC<<endl;*/ dProgres.setEstadoBarraProgreso(1); dProgres.setPercentText(1); Utiles::actualizarInterfaz(); dProgres.cierraVentanaProgreso(); /**************************************************************************/ } else { return false; } return true; }