00001
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <new>
00023 #include <string.h>
00024 #include <MicrosoftBMP_RT.h>
00025 #include <MicrosoftRCBMP_RT.h>
00026 #include <MicrosoftMonoBMP_RT.h>
00027 #include <math.h>
00028 #include <limits.h>
00029 #include <stdlib.h>
00030 #include <iostream>
00031
00032 using namespace std;
00033
00034 #include "ImageGrey.h"
00035
00036 static int int_compare(const void *i1, const void *i2) ;
00037
00038 ImageGrey::ImageGrey(ImageGrey& img) : ImageBase(img)
00044 {
00045 unsigned int array_size = img.width * img.height;
00046 brightness = new PixelGrey[array_size];
00047
00048 *this = img;
00049 }
00050
00051
00052 ImageGrey::ImageGrey(unsigned int w, unsigned int h) : ImageBase(w,h)
00059 {
00060 unsigned int array_size = width * height;
00061 brightness = new PixelGrey[array_size];
00062
00063
00064 }
00065
00066 ImageGrey::ImageGrey(char *filename, FileFormat format)
00075 {
00076
00077 if(format == FORMAT_BMP_24){
00078 MicrosoftBMP_RT bmp(filename) ;
00079
00080 if(!bmp.read()) throw("Invalid Bitmap file specified") ;
00081
00082 width = bmp.ImageWidth ;
00083 height = bmp.ImageHeight ;
00084
00085 brightness = new int[width*height] ;
00086
00087 bmp.extract_data_grey((int *)brightness) ;
00088 }
00089 else if(format == FORMAT_BMP_RC){
00090 MicrosoftRCBMP_RT bmp(filename) ;
00091
00092 if(!bmp.read()) throw("Invalid Bitmap file specified") ;
00093
00094 width = bmp.ImageWidth ;
00095 height = bmp.ImageHeight ;
00096
00097 brightness = new int[width*height] ;
00098
00099 bmp.extract_data_grey((int *)brightness) ;
00100 }
00101 else if(format == FORMAT_BMP_MONO){
00102 MicrosoftMonoBMP_RT bmp(filename) ;
00103
00104 if(!bmp.read()) throw("Invalid Bitmap file specified") ;
00105
00106 width = bmp.ImageWidth ;
00107 height = bmp.ImageHeight ;
00108
00109 brightness = new int[width*height] ;
00110
00111 bmp.extract_data_grey((int *)brightness) ;
00112 }
00113 else if(format == FORMAT_BMP_ANY){
00114
00115 MicrosoftBMP_RT* bmp ;
00116 MicrosoftRCBMP_RT *bmp_rc;
00117 MicrosoftMonoBMP_RT *bmp_mono;
00118
00119 if((bmp = new MicrosoftBMP_RT(filename)) != NULL &&
00120 bmp->read()){
00121
00122 width = bmp->ImageWidth ;
00123 height = bmp->ImageHeight ;
00124
00125 brightness = new int[width*height] ;
00126
00127 bmp->extract_data_grey((int *)brightness) ;
00128 }
00129 else if((bmp_rc = new MicrosoftRCBMP_RT(filename)) != NULL &&
00130 bmp_rc->read()){
00131
00132 width = bmp_rc->ImageWidth ;
00133 height = bmp_rc->ImageHeight ;
00134
00135 brightness = new int[width*height] ;
00136
00137 bmp_rc->extract_data_grey((int *)brightness) ;
00138
00139 }
00140 else if((bmp_mono = new MicrosoftMonoBMP_RT(filename)) != NULL &&
00141 bmp_mono->read()){
00142
00143 width = bmp_mono->ImageWidth ;
00144 height = bmp_mono->ImageHeight ;
00145
00146 brightness = new int[width*height] ;
00147
00148 bmp_mono->extract_data_grey((int *)brightness) ;
00149 }
00150 }
00151
00152
00153
00154
00155 }
00156
00157
00158 ImageGrey::ImageGrey(ImageGrey& img,
00159 unsigned int min_x,
00160 unsigned int min_y,
00161 unsigned int max_x,
00162 unsigned int max_y) :
00163 ImageBase(max_x-min_x+1, max_y-min_y+1)
00172 {
00173 brightness = new int[width*height];
00174 copy(img, min_x, min_y, max_x, max_y, 0, 0) ;
00175 }
00176
00177
00178 ImageGrey::~ImageGrey()
00182 {
00183 delete [] brightness;
00184 }
00185
00186
00187 void ImageGrey::set_pixel(unsigned int x, unsigned int y, PixelGrey level)
00195 {
00196
00197 if (x > width || y > height)
00198 throw "Invalid Coordinates in method set_rgb";
00199
00200 unsigned int offset = y * width + x;
00201 brightness[offset] = level;
00202 }
00203
00204
00205 void ImageGrey::get_pixel(unsigned int x, unsigned int y, PixelGrey& p)
00213 {
00214 p = brightness[y * width + x];
00215 }
00216
00217
00218
00219 ImageGrey& ImageGrey::clear(int k)
00225 {
00226 int *start = brightness;
00227 int *end = start + width * height;
00228
00229 for (int *d = start; d < end; d++) *d = k;
00230
00231 return *this;
00232 }
00233
00234
00235 ImageGrey& ImageGrey::copy(ImageGrey& img)
00242 {
00243
00244 if (this == &img)
00245 throw "Source and Destination are same Image";
00246
00247
00248 if (width != img.width || height != img.height)
00249 throw "Difference in image dimensions";
00250
00251
00252 memcpy(brightness, img.brightness, width * height * sizeof(int));
00253
00254 return *this;
00255 }
00256
00257 ImageGrey& ImageGrey::copy(ImageGrey& img,
00258 unsigned int min_x,
00259 unsigned int min_y,
00260 unsigned int max_x,
00261 unsigned int max_y,
00262 unsigned int start_x,
00263 unsigned int start_y)
00276 {
00277 unsigned int sx ;
00278 unsigned int sy ;
00279 unsigned int cntx ;
00280 unsigned int cnty ;
00281 int *s_ptr ;
00282 int *d_ptr ;
00283 unsigned int s_width ;
00284
00285 s_width = img.get_width() ;
00286
00287
00288 if (this == &img)
00289 throw "Source and Destination are same Image";
00290
00291
00292 if(min_x > max_x || min_y > max_y)
00293 throw "Invalid arguments to ImageRGB::copy()" ;
00294
00295
00296 sx = max_x - min_x + 1 ;
00297 sy = max_y - min_y + 1 ;
00298
00299 if(sx+start_x > width ||
00300 sy+start_y > height)
00301 throw "Dest. image is not big enough" ;
00302
00303 if(max_x > s_width ||
00304 max_y > img.get_height() )
00305 throw "Source images is not big enough" ;
00306
00307 for(cnty=0 ; cnty<sy ; cnty++){
00308
00309 s_ptr = (int*)img.brightness + (min_x + (min_y+cnty)*s_width) ;
00310 d_ptr = (int*)brightness + (start_x + (start_y+cnty)*width) ;
00311
00312 for(cntx=0 ; cntx<sx ; cntx++){
00313
00314 *(d_ptr++) = *(s_ptr++) ;
00315 }
00316 }
00317
00318 return *this;
00319 }
00320
00321 ImageGrey& ImageGrey::operator += (int fact)
00327 {
00328 unsigned int cnt ;
00329 unsigned int sz ;
00330 int *p1 ;
00331
00332 sz = width * height ;
00333 p1 = brightness ;
00334
00335 for(cnt=0 ; cnt<sz ; cnt++, p1++){
00336 *p1 += fact ;
00337 }
00338
00339 return *this;
00340 }
00341
00342 ImageGrey& ImageGrey::operator -= (int fact)
00348 {
00349 unsigned int cnt ;
00350 unsigned int sz ;
00351 int *p1 ;
00352
00353 sz = width * height ;
00354 p1 = brightness ;
00355
00356 for(cnt=0 ; cnt<sz ; cnt++, p1++){
00357 *p1 -= fact ;
00358 }
00359
00360 return *this;
00361 }
00362
00363 ImageGrey& ImageGrey::operator *= (int fact)
00369 {
00370 unsigned int cnt ;
00371 unsigned int sz ;
00372 int *p1 ;
00373
00374 sz = width * height ;
00375 p1 = brightness ;
00376
00377 for(cnt=0 ; cnt<sz ; cnt++, p1++){
00378 *p1 *= fact ;
00379 }
00380
00381 return *this;
00382 }
00383
00384 ImageGrey& ImageGrey::operator /= (int fact)
00390 {
00391 unsigned int cnt ;
00392 unsigned int sz ;
00393 int *p1 ;
00394
00395 sz = width * height ;
00396 p1 = brightness ;
00397
00398 for(cnt=0 ; cnt<sz ; cnt++, p1++){
00399 *p1 /= fact ;
00400 }
00401
00402 return *this;
00403 }
00404
00405
00406 ImageGrey& ImageGrey::operator -= (ImageGrey& img)
00412 {
00413 unsigned int cnt ;
00414 unsigned int sz ;
00415 int *p1 ;
00416 int *p2 ;
00417
00418 sz = width * height ;
00419 p1 = brightness ;
00420 p2 = img.brightness ;
00421
00422 for(cnt=0 ; cnt<sz ; cnt++, p1++, p2++){
00423 *p1 -= *p2 ;
00424 }
00425
00426 return *this;
00427 }
00428
00429 void ImageGrey::absolute()
00434 {
00435 unsigned int cnt ;
00436 unsigned int sz ;
00437 int *p1 ;
00438
00439 p1 = brightness ;
00440 sz = width * height ;
00441
00442 for(cnt=0 ; cnt<sz ; cnt++, p1++){
00443 if(*p1<0) *p1 = -(*p1) ;
00444 }
00445
00446 return ;
00447 }
00448
00449 void ImageGrey::threshold(int thresh)
00455 {
00456 unsigned int cnt ;
00457 unsigned int sz ;
00458 int *p1 ;
00459
00460 p1 = brightness ;
00461 sz = width * height ;
00462
00463 for(cnt=0 ; cnt<sz ; cnt++, p1++){
00464 if(*p1<thresh) *p1 = 0 ;
00465 else *p1 = 255 ;
00466 }
00467
00468 return ;
00469 }
00470
00471 bool ImageGrey::save(char *filename, FileFormat format)
00478 {
00479
00480 bool ret_val = true ;
00481
00482 if(format == FORMAT_BMP_24){
00483
00484 MicrosoftBMP_RT *btmp;
00485 btmp = new MicrosoftBMP_RT(filename);
00486 if(btmp==NULL) ret_val = false ;
00487 else if(!btmp->set_size(width,height)) ret_val = false ;
00488 else{
00489 btmp->put_data_grey((int *)brightness) ;
00490 ret_val = btmp->write();
00491 }
00492 delete btmp ;
00493 }
00494 if(format == FORMAT_BMP_RC || format == FORMAT_BMP_ANY){
00495
00496 MicrosoftRCBMP_RT *btmp;
00497 btmp = new MicrosoftRCBMP_RT(filename);
00498 if(btmp==NULL) ret_val = false ;
00499 else if(!btmp->set_size(width,height)) ret_val = false ;
00500 else if(!btmp->set_palette_grey256()) ret_val = false ;
00501 else{
00502 btmp->put_data_grey((int *)brightness) ;
00503 ret_val = btmp->write();
00504 }
00505 delete btmp ;
00506 }
00507 if(format == FORMAT_BMP_MONO){
00508
00509 MicrosoftMonoBMP_RT *btmp;
00510 btmp = new MicrosoftMonoBMP_RT(filename);
00511 if(btmp==NULL) ret_val = false ;
00512 else if(!btmp->set_size(width,height)) ret_val = false ;
00513 else{
00514 btmp->put_data_grey((int *)brightness) ;
00515 ret_val = btmp->write();
00516 }
00517 delete btmp ;
00518 }
00519
00520
00521
00522 return ret_val ;
00523 }
00524
00525 bool ImageGrey::sobel_horizontal(ImageGrey &result)
00532 {
00533 bool ret_val = true ;
00534 int *ob_ptr ;
00535 int *rs_ptr ;
00536 int *tl_ptr ;
00537 int *tr_ptr ;
00538 int *b_ptr ;
00539 int *t_ptr ;
00540 int *bl_ptr ;
00541 int *br_ptr ;
00542 unsigned int cnt_x ;
00543 unsigned int cnt_y ;
00544 register int pix_val ;
00545
00546 if(result.get_width() != width ||
00547 result.get_height() != height ){
00548 ret_val = false ;
00549 }
00550 else{
00551 ob_ptr = brightness ;
00552 rs_ptr = result.brightness ;
00553 tl_ptr = ob_ptr - width - 1 ;
00554 tr_ptr = ob_ptr - width + 1 ;
00555 t_ptr = ob_ptr - width ;
00556 b_ptr = ob_ptr + width ;
00557 bl_ptr = ob_ptr + width - 1 ;
00558 br_ptr = ob_ptr + width + 1 ;
00559 for(cnt_y=0 ; cnt_y<height ; cnt_y++){
00560 for(cnt_x=0 ; cnt_x<width ; cnt_x++, ob_ptr++, rs_ptr++, tl_ptr++,
00561 tr_ptr++,b_ptr++,t_ptr++,bl_ptr++,br_ptr++){
00562 if(cnt_y>0 &&
00563 cnt_x>0 &&
00564 cnt_y<height-1 &&
00565 cnt_x<width-1 ){
00566 pix_val = -1 * (*tl_ptr) +
00567 -2 * (*t_ptr) +
00568 -1 * (*tr_ptr) +
00569 1 * (*bl_ptr) +
00570 2 * (*b_ptr) +
00571 1 * (*br_ptr) ;
00572 *rs_ptr = pix_val / 8 ;
00573 }
00574 else{
00575 *rs_ptr = 0 ;
00576 }
00577 }
00578 }
00579 }
00580
00581 return ret_val ;
00582
00583 }
00584
00585 bool ImageGrey::sobel_vertical(ImageGrey &result)
00592 {
00593 bool ret_val = true ;
00594 int *ob_ptr ;
00595 int *rs_ptr ;
00596 int *tl_ptr ;
00597 int *tr_ptr ;
00598 int *l_ptr ;
00599 int *r_ptr ;
00600 int *bl_ptr ;
00601 int *br_ptr ;
00602 unsigned int cnt_x ;
00603 unsigned int cnt_y ;
00604 register int pix_val ;
00605
00606 if(result.get_width() != width ||
00607 result.get_height() != height ){
00608 ret_val = false ;
00609 }
00610 else{
00611 ob_ptr = brightness ;
00612 rs_ptr = result.brightness ;
00613 l_ptr = ob_ptr - 1 ;
00614 r_ptr = ob_ptr + 1 ;
00615 tl_ptr = ob_ptr - width - 1 ;
00616 tr_ptr = ob_ptr - width + 1 ;
00617 bl_ptr = ob_ptr + width - 1 ;
00618 br_ptr = ob_ptr + width + 1 ;
00619 for(cnt_y=0 ; cnt_y<height ; cnt_y++){
00620 for(cnt_x=0 ; cnt_x<width ; cnt_x++, ob_ptr++, rs_ptr++, tl_ptr++,
00621 tr_ptr++,l_ptr++,r_ptr++,bl_ptr++,br_ptr++){
00622 if(cnt_y>0 &&
00623 cnt_x>0 &&
00624 cnt_y<height-1 &&
00625 cnt_x<width-1 ){
00626
00627 pix_val = -1 * *tl_ptr +
00628 -2 * *l_ptr +
00629 -1 * *bl_ptr +
00630 1 * *tr_ptr +
00631 2 * *r_ptr +
00632 1 * *br_ptr ;
00633 *rs_ptr = pix_val / 8 ;
00634 }
00635 else{
00636 *rs_ptr = 0 ;
00637 }
00638 }
00639 }
00640 }
00641
00642 return ret_val ;
00643 }
00644
00645 bool ImageGrey::sobel(ImageGrey &result)
00653 {
00654 bool ret_val = true ;
00655 int *ob_ptr ;
00656 int *rs_ptr ;
00657 int *tl_ptr ;
00658 int *tr_ptr ;
00659 int *l_ptr ;
00660 int *r_ptr ;
00661 int *t_ptr ;
00662 int *b_ptr ;
00663 int *bl_ptr ;
00664 int *br_ptr ;
00665 unsigned int cnt_x ;
00666 unsigned int cnt_y ;
00667 register int pix_val_h ;
00668 register int pix_val_v ;
00669
00670 if(result.get_width() != width ||
00671 result.get_height() != height ){
00672 ret_val = false ;
00673 }
00674 else{
00675 ob_ptr = brightness ;
00676 rs_ptr = result.brightness ;
00677 l_ptr = ob_ptr - 1 ;
00678 r_ptr = ob_ptr + 1 ;
00679 t_ptr = ob_ptr - width ;
00680 b_ptr = ob_ptr + width ;
00681 tl_ptr = ob_ptr - width - 1 ;
00682 tr_ptr = ob_ptr - width + 1 ;
00683 bl_ptr = ob_ptr + width - 1 ;
00684 br_ptr = ob_ptr + width + 1 ;
00685 for(cnt_y=0 ; cnt_y<height ; cnt_y++){
00686 for(cnt_x=0 ; cnt_x<width ; cnt_x++, ob_ptr++, rs_ptr++, tl_ptr++,
00687 tr_ptr++,l_ptr++,r_ptr++,bl_ptr++,br_ptr++, t_ptr++, b_ptr++){
00688 if(cnt_y>0 &&
00689 cnt_x>0 &&
00690 cnt_y<height-1 &&
00691 cnt_x<width-1 ){
00692
00693 pix_val_h = -1 * (*tl_ptr) +
00694 -2 * (*t_ptr) +
00695 -1 * (*tr_ptr) +
00696 1 * (*bl_ptr) +
00697 2 * (*b_ptr) +
00698 1 * (*br_ptr) ;
00699
00700 pix_val_v = -1 * *tl_ptr +
00701 -2 * *l_ptr +
00702 -1 * *bl_ptr +
00703 1 * *tr_ptr +
00704 2 * *r_ptr +
00705 1 * *br_ptr ;
00706
00707 *rs_ptr = (int)sqrt((double)(pix_val_h*pix_val_h +
00708 pix_val_v*pix_val_v)) ;
00709 }
00710 else{
00711 *rs_ptr = 0 ;
00712 }
00713 }
00714 }
00715 }
00716
00717 return ret_val ;
00718 }
00719
00720 bool ImageGrey::dilate(ImageGrey &result)
00728 {
00729 bool ret_val = true ;
00730 unsigned int cnt_x ;
00731 unsigned int cnt_y ;
00732 int *ob_ptr ;
00733 int *rs_ptr ;
00734 int *ne_ptr ;
00735
00736 ob_ptr = brightness ;
00737 rs_ptr = result.brightness ;
00738
00739 if(result.get_width() != width ||
00740 result.get_height() != height ){
00741
00742 ret_val = false ;
00743 }
00744 else{
00745 for(cnt_y=0; cnt_y<height; cnt_y++){
00746 for(cnt_x=0; cnt_x<width; cnt_x++, ob_ptr++, rs_ptr++){
00747 *rs_ptr = *ob_ptr ;
00748 if( cnt_y>0 &&
00749 cnt_x>0 &&
00750 cnt_x<width-1 &&
00751 cnt_y<height-1){
00752
00753 if(!(*ob_ptr)){
00754
00755 ne_ptr = ob_ptr - width - 1 ;
00756 if(*(ne_ptr++)) *rs_ptr = 255 ;
00757 if(*(ne_ptr++)) *rs_ptr = 255 ;
00758 if(*ne_ptr) *rs_ptr = 255 ;
00759 ne_ptr += width ;
00760 if(*(ne_ptr--)) *rs_ptr = 255 ;
00761 ne_ptr-- ;
00762 if(*ne_ptr) *rs_ptr = 255 ;
00763 ne_ptr += width ;
00764 if(*(ne_ptr++)) *rs_ptr = 255 ;
00765 if(*(ne_ptr++)) *rs_ptr = 255 ;
00766 if(*ne_ptr) *rs_ptr = 255 ;
00767 }
00768 }
00769 }
00770 }
00771 }
00772
00773 return ret_val ;
00774
00775 }
00776
00777 bool ImageGrey::errode(ImageGrey &result)
00781 {
00782 return erode(result) ;
00783 }
00784
00785 bool ImageGrey::erode(ImageGrey &result)
00793 {
00794 bool ret_val = true ;
00795 unsigned int cnt_x ;
00796 unsigned int cnt_y ;
00797 int *ob_ptr ;
00798 int *rs_ptr ;
00799 int *ne_ptr ;
00800
00801 ob_ptr = brightness ;
00802 rs_ptr = result.brightness ;
00803
00804 if(result.get_width() != width ||
00805 result.get_height() != height ){
00806
00807 ret_val = false ;
00808 }
00809 else{
00810 for(cnt_y=0; cnt_y<height; cnt_y++){
00811 for(cnt_x=0; cnt_x<width; cnt_x++, ob_ptr++, rs_ptr++){
00812 *rs_ptr = *ob_ptr ;
00813 if( cnt_y>0 &&
00814 cnt_x>0 &&
00815 cnt_x<width-1 &&
00816 cnt_y<height-1){
00817
00818 if(*ob_ptr){
00819
00820 ne_ptr = ob_ptr - width - 1 ;
00821 if(!*(ne_ptr++)) *rs_ptr = 0 ;
00822 if(!*(ne_ptr++)) *rs_ptr = 0 ;
00823 if(!*ne_ptr) *rs_ptr = 0 ;
00824 ne_ptr += width ;
00825 if(!*(ne_ptr--)) *rs_ptr = 0 ;
00826 ne_ptr-- ;
00827 if(!*ne_ptr) *rs_ptr = 0 ;
00828 ne_ptr += width ;
00829 if(!*(ne_ptr++)) *rs_ptr = 0 ;
00830 if(!*(ne_ptr++)) *rs_ptr = 0 ;
00831
00832 if(!*ne_ptr) *rs_ptr = 0 ;
00833 }
00834 }
00835 }
00836 }
00837 }
00838
00839 return ret_val ;
00840 }
00841
00842 bool ImageGrey::extract_region(int region_no, ImageGrey &result)
00850 {
00851 int *ob_ptr ;
00852 int *rs_ptr ;
00853 bool ret_val = true ;
00854
00855 if(result.get_width() != width ||
00856 result.get_height() != height ){
00857
00858 ret_val = false ;
00859 }
00860 else{
00861 for( ob_ptr = brightness, rs_ptr = result.brightness ;
00862 ob_ptr < brightness + width*height ;
00863 ob_ptr++, rs_ptr++){
00864
00865 if(*ob_ptr == region_no){
00866 *rs_ptr = 255 ;
00867 }
00868 else{
00869 *rs_ptr = 0 ;
00870 }
00871 }
00872 }
00873
00874 return ret_val;
00875 }
00876
00877 bool ImageGrey::region_identify(unsigned int max_regions,
00878 unsigned int &actual_regions,
00879 ImageGrey &result)
00891 {
00892 bool ret_val = true ;
00893 int next_label = 1 ;
00894 equivalence *equiv_latest=NULL;
00895 equivalence *equiv_ptr=NULL;
00896 int *ob_ptr ;
00897 int *rs_ptr ;
00898 int *ne_ptr = NULL ;
00899 unsigned int cnt_x;
00900 unsigned int cnt_y;
00901 int cnt;
00902 int cnt2;
00903 unsigned int region_no;
00904 unsigned int region_freq;
00905 int neighbours[4] ;
00906 int *frequency;
00907 bool is_significant;
00908
00909 ob_ptr = brightness ;
00910 rs_ptr = result.brightness ;
00911
00912 if( max_regions <= 0 ||
00913 result.get_width() != width ||
00914 result.get_height() != height ){
00915
00916 ret_val = false ;
00917 }
00918 else{
00919
00920
00921
00922
00923
00924
00925
00926
00927 for( ob_ptr = brightness, rs_ptr = result.brightness, cnt_x=0,
00928 cnt_y=0;
00929 (unsigned long)(ob_ptr - brightness) <width*height;
00930 cnt_x++, ob_ptr++, rs_ptr++){
00931
00932 *rs_ptr = 0;
00933 if(cnt_x==width){
00934
00935 cnt_x=0;
00936 cnt_y++;
00937 }
00938 else if( cnt_y>0 &&
00939 cnt_y<height-1 &&
00940 cnt_x>0 &&
00941 cnt_x<width-1 &&
00942 *ob_ptr ){
00943
00944 ne_ptr = rs_ptr - width - 1 ;
00945 neighbours[0] = *(ne_ptr++);
00946 neighbours[1] = *(ne_ptr++);
00947 neighbours[2] = *ne_ptr++;
00948 neighbours[3] = *(rs_ptr-1);
00949 qsort(neighbours , 4, sizeof(int), int_compare);
00950
00951 if(neighbours[3] == 0){
00952
00953 *rs_ptr = next_label++;
00954 }
00955 else{
00956
00957 for(cnt=3; cnt>=0 && ret_val; cnt--){
00958 if(neighbours[cnt]){
00959 *rs_ptr=neighbours[cnt];
00960 if(neighbours[cnt] != neighbours[3]){
00961 ret_val = new_equivalence(neighbours[cnt],
00962 neighbours[3],
00963 &equiv_latest);
00964 }
00965 }
00966 }
00967 }
00968 }
00969 }
00970
00971
00972
00973
00974 frequency = new int[next_label];
00975
00976 if(frequency==NULL) ret_val = false ;
00977 for(cnt=0; cnt<next_label && ret_val; cnt++) frequency[cnt]=0;
00978
00979 for( ob_ptr = brightness, rs_ptr = result.brightness, cnt_x=0,
00980 cnt_y=0;
00981 (unsigned long)(ob_ptr - brightness) <width*height && ret_val;
00982 cnt_x++, ob_ptr++, rs_ptr++){
00983
00984 if(cnt_x==width){
00985
00986 cnt_x=0;
00987 cnt_y++;
00988 }
00989 else if( cnt_y>0 &&
00990 cnt_y<height-1 &&
00991 cnt_x>0 &&
00992 cnt_x<width-1 &&
00993 *rs_ptr ){
00994
00995 for(cnt=next_label-1; cnt>=0; cnt--){
00996 equiv_ptr = equiv_latest ;
00997 while(equiv_ptr != NULL){
00998
00999 if(*rs_ptr == cnt && equiv_ptr->eq2 == cnt){
01000 *rs_ptr = equiv_ptr->eq1;
01001 }
01002 equiv_ptr = equiv_ptr->next ;
01003 }
01004 }
01005 frequency[*rs_ptr]++;
01006 }
01007 }
01008
01009
01010
01011
01012
01013 free_equivalence(&equiv_latest);
01014
01015 actual_regions = 0 ;
01016
01017 for(cnt=0; cnt<(int)max_regions; cnt++){
01018 region_freq=frequency[1];
01019 region_no = 1;
01020 for(cnt2=1; cnt2<next_label-1; cnt2++){
01021 if(frequency[cnt2] > (int)region_freq){
01022 region_freq = frequency[cnt2];
01023 region_no = cnt2;
01024 }
01025 }
01026 if(region_freq){
01027 frequency[region_no] = 0;
01028 ret_val = new_equivalence(cnt+1,
01029 region_no,
01030 &equiv_latest);
01031 actual_regions++;
01032 }
01033 }
01034
01035
01036
01037
01038 for( ob_ptr = brightness, rs_ptr = result.brightness, cnt_x=0,
01039 cnt_y=0;
01040 (unsigned long)(ob_ptr - brightness) <width*height && ret_val;
01041 cnt_x++, ob_ptr++, rs_ptr++){
01042
01043 if(cnt_x==width){
01044
01045 cnt_x=0;
01046 cnt_y++;
01047 }
01048 else if( cnt_y>0 &&
01049 cnt_y<height-1 &&
01050 cnt_x>0 &&
01051 cnt_x<width-1 &&
01052 *rs_ptr ){
01053
01054 equiv_ptr = equiv_latest ;
01055 is_significant=false;
01056 while(equiv_ptr != NULL && !is_significant){
01057
01058 if(*rs_ptr == equiv_ptr->eq2){
01059 *rs_ptr = equiv_ptr->eq1;
01060 is_significant=true;
01061 }
01062 equiv_ptr = equiv_ptr->next ;
01063 }
01064 if(!is_significant){
01065
01066 *rs_ptr = 0;
01067 }
01068 }
01069 }
01070 }
01071
01072 return ret_val;
01073
01074 }
01075
01076 static int int_compare(const void *i1, const void *i2)
01077 {
01078
01079
01080
01081
01082 int ret_val ;
01083
01084 if( *((int *)i1) < *((int *)i2) ){
01085 ret_val = -1 ;
01086 }
01087 else{
01088 ret_val = 1 ;
01089 }
01090 return ret_val ;
01091 }
01092
01093 bool ImageGrey::new_equivalence(int low, int high, equivalence **latest)
01094 {
01095
01096
01097
01098
01099
01100 bool ret_val = true;
01101 equivalence *new_eq=NULL;
01102 equivalence *eq_ptr = *latest ;
01103 bool exists = false ;
01104
01105
01106
01107 while(eq_ptr != NULL && !exists){
01108 if(eq_ptr->eq2 == high) {exists = true;}
01109 else {eq_ptr = eq_ptr->next;}
01110 }
01111
01112 if(!exists){
01113
01114 new_eq = new equivalence ;
01115 if(new_eq == NULL) ret_val = false;
01116 }
01117
01118 if(ret_val && exists && low<eq_ptr->eq1){
01119
01120 ret_val = new_equivalence(low,eq_ptr->eq1,latest);
01121 eq_ptr->eq1 = low;
01122 }
01123 else if(ret_val && exists && low>eq_ptr->eq1){
01124 ret_val = new_equivalence(eq_ptr->eq1, low, latest);
01125 }
01126
01127 if (ret_val && !exists){
01128
01129 new_eq->eq1 = low;
01130 new_eq->eq2 = high;
01131 new_eq->next = *latest;
01132 *latest = new_eq ;
01133 }
01134
01135 return ret_val;
01136 }
01137
01138 void ImageGrey::free_equivalence(equivalence **eq)
01139 {
01140
01141
01142
01143
01144 equivalence *eq_ptr1 = *eq;
01145 equivalence *eq_ptr2;
01146
01147 while(eq_ptr1 != NULL){
01148 eq_ptr2 = eq_ptr1->next ;
01149 delete eq_ptr1;
01150 eq_ptr1= eq_ptr2 ;
01151 }
01152
01153 *eq = NULL;
01154 }
01155
01156 void ImageGrey::normalise_intensity(float mean,
01157 float sd)
01165 {
01166 unsigned int cnt ;
01167 unsigned int sz ;
01168 int *ptr ;
01169 float c_mean = 0 ;
01170 float c_sd = 0 ;
01171 float nval ;
01172 float sf ;
01173
01174 sz = width*height ;
01175
01176
01177 for(cnt=0, ptr=brightness ; cnt<sz ; cnt++, ptr++){
01178 c_mean += *ptr ;
01179 c_sd += *ptr * *ptr ;
01180 }
01181 c_mean /= sz ;
01182 c_sd /= sz ;
01183 c_sd -= c_mean*c_mean ;
01184 c_sd = sqrt(c_sd) ;
01185
01186 sf = sd / c_sd ;
01187
01188
01189 for(cnt=0, ptr=brightness ; cnt<sz ; cnt++, ptr++){
01190 nval = *ptr - c_mean ;
01191 nval *= sf ;
01192 nval += mean ;
01193 *ptr = (int)nval ;
01194 }
01195 }
01196
01197 void ImageGrey::normalise_intensity_range()
01202 {
01203 unsigned int cnt ;
01204 unsigned int sz ;
01205 int *ptr ;
01206 int min = INT_MAX ;
01207 int max = -INT_MAX ;
01208 float sf ;
01209
01210 sz = width*height ;
01211
01212
01213 for(cnt=0, ptr=brightness ; cnt<sz ; cnt++, ptr++){
01214 if(*ptr < min) min = *ptr ;
01215 if(*ptr > max) max = *ptr ;
01216 }
01217
01218 if(max > min){
01219 sf = 255.0 / (float)(max - min) ;
01220 }
01221 else{
01222 return ;
01223 }
01224
01225
01226 for(cnt=0, ptr=brightness ; cnt<sz ; cnt++, ptr++){
01227 *ptr -= min ;
01228 *ptr *= sf ;
01229 }
01230 }
01231
01232 bool ImageGrey:: median(unsigned int n, unsigned int m,
01233 ImageGrey &result)
01238 {
01239 bool ret_val = true ;
01240 unsigned int border_x;
01241 unsigned int border_y;
01242 unsigned int image_x ;
01243 unsigned int image_y ;
01244 unsigned int matrix_x ;
01245 unsigned int matrix_y ;
01246 int *neighbourhood;
01247 unsigned int n_count;
01248
01249 border_x = n / 2 ;
01250 border_y = m/ 2 ;
01251
01252
01253 neighbourhood = new int[n*m] ;
01254
01255 for(image_y=0; image_y<height; image_y++){
01256 for(image_x=0; image_x<width; image_x++){
01257 if(image_y<border_y ||
01258 image_x<border_x ||
01259 image_y>=height-border_y ||
01260 image_x>=width-border_x){
01261
01262 result.brightness[image_y*width + image_x] = 0;
01263 }
01264 else{
01265 n_count = 0 ;
01266 for(matrix_x=0; matrix_x<n; matrix_x++){
01267 for(matrix_y=0; matrix_y<m; matrix_y++){
01268 neighbourhood[n_count] =
01269 brightness[(image_y+matrix_y-border_y)*width
01270 + image_x + matrix_x - border_x] ;
01271 n_count++;
01272 }
01273 }
01274 qsort(neighbourhood , n*m, sizeof(int), int_compare);
01275 result.brightness[image_y*width + image_x] =
01276 neighbourhood[n*m/2+1] ;
01277 }
01278 }
01279 }
01280
01281 delete [] neighbourhood ;
01282
01283 return ret_val ;
01284 }
01285
01286 bool ImageGrey::remove_point_noise(ImageGrey &result)
01291 {
01292 unsigned int image_x ;
01293 unsigned int image_y ;
01294 int *ptr ;
01295 int *rptr ;
01296
01297 ptr = brightness ;
01298 rptr = result.brightness ;
01299 for(image_y=0; image_y<height; image_y++){
01300 for(image_x=0; image_x<width; image_x++, ptr++, rptr++){
01301 if(*ptr &&
01302 ((image_x==0 && image_y==0) || *(ptr-width-1)==0) &&
01303 (image_y==0 || *(ptr-width)==0) &&
01304 ((image_x==width-1 && image_y==0) || *(ptr-width+1)==0) &&
01305 (image_x==0 || *(ptr-1)==0) &&
01306 (image_x==width-1 || *(ptr+1)==0) &&
01307 ((image_x==0 && image_y==height-1) || *(ptr+width-1)==0) &&
01308 (image_y==height-1 || *(ptr+width)==0) &&
01309 ((image_x==width-1 && image_y==height-1) || *(ptr+width+1)==0)){
01310
01311 *rptr = 0 ;
01312 }
01313 else{
01314 *rptr = *ptr ;
01315 }
01316 }
01317 }
01318
01319 return true ;
01320 }
01321