c - Image pixel scaling error - calculating SNR of CCD lens -
i trying calculate signal noise ratio of 2 loaded images taken same digital camera. idea calculate signal noise @ numerous light levels achieve graph shows signal noise ratio of ccd lens.
the problem facing @ moment that; when scale second image (image b) have same average pixel intensity first image (image a), value achieved not exact value first image. think problem result of rounding error image conversions.
the method use calculate snr is:
- convert images gray scale
- convert images 16 bit signed
- subtract image b a
- get average pixel intensity of subtraction
- subtract average value , b (to eliminate noise)
- convert 8 bit unsigned
- get average pixel values of both images
- get ratio of average values
- scale image b (16 bit unsigned) ratio average pixel value of image - problem area
- convert 8 bit , calculate average pixel intensity
- subtract images each other again eliminate last random noise
- calculate standard deviation of subtraction
- convert standard deviation variance
i new @ opencv , programming in general, better methods , on specific problem appreciated.
int _tmain(int argc, _tchar* argv[]) { float mean_a; float mean_b1; float var,mean_b; float grey_b_mul; float grey_sub2; float o, standard, r; iplimage *img = cvloadimage("j:\\backup\\fotos\\img_0168.jpg", 3);//define images iplimage *img2 = cvloadimage("j:\\backup\\fotos\\img_0164.jpg", 3); iplimage *graya = cvcreateimage(cvgetsize(img),ipl_depth_8u, 1); iplimage *grayb = cvcreateimage(cvgetsize(img),ipl_depth_8u, 1); iplimage *gray1 = cvcreateimage(cvgetsize(img),ipl_depth_16u, 1); iplimage *gray1s = cvcreateimage(cvgetsize(img),ipl_depth_16s, 1); iplimage *gray2s = cvcreateimage(cvgetsize(img),ipl_depth_16s, 1); iplimage *gray2 = cvcreateimage(cvgetsize(img),ipl_depth_16u, 1); iplimage *sub1 = cvcreateimage(cvgetsize(img),ipl_depth_16s, 1); iplimage *imga = cvcreateimage(cvgetsize(img),ipl_depth_8u, 1); iplimage *imga1 = cvcreateimage(cvgetsize(img),ipl_depth_16s, 1); iplimage *imga1u = cvcreateimage(cvgetsize(img),ipl_depth_16u, 1); iplimage *imgb1u = cvcreateimage(cvgetsize(img),ipl_depth_16u, 1); iplimage *imgb1 = cvcreateimage(cvgetsize(img),ipl_depth_16s, 1); iplimage *imgb = cvcreateimage(cvgetsize(img),ipl_depth_8u, 1); iplimage *imgb_mul = cvcreateimage(cvgetsize(img),ipl_depth_16u, 1); iplimage *imgb_mull = cvcreateimage(cvgetsize(img),ipl_depth_16u, 1); iplimage *imgb_scaled = cvcreateimage(cvgetsize(img),ipl_depth_16s, 1); iplimage *imgbsc = cvcreateimage(cvgetsize(img),ipl_depth_8u, 1); iplimage *sub2 = cvcreateimage(cvgetsize(img),ipl_depth_16s, 1); iplimage *sub2u = cvcreateimage(cvgetsize(img),ipl_depth_16u, 1); iplimage *sub2_final = cvcreateimage(cvgetsize(img),ipl_depth_8u, 1); if (img->nchannels ==3) { cvcvtcolor(img, graya, cv_bgr2gray); //convert grayscale cvcvtcolor(img2, grayb, cv_bgr2gray); } else { cvcopyimage(img,graya); cvcopyimage(img2,grayb); } cvscalar m = cvavg(graya, 0); //calculate average pixel intensity double z = m.val[0]; cvscalar n = cvavg(grayb, 0); //calculate average pixel intensity double y = n.val[0]; if (z > 128) //convert 16 bit signed { cvconvertscale(graya, gray1, 256.0, -32768); cvconvertscale(gray1, gray1s, 1.0); } else cvconvertscale(graya, gray1s, 256.0, -32768); if (y> 128) { cvconvertscale(grayb, gray2, 256.0, -32768); cvconvertscale(gray2, gray2s, 1.0); } else cvconvertscale(grayb, gray2s, 256.0, -32768); cvnamedwindow("ccd noise",1); cvnamedwindow("image a",1); cvnamedwindow("image b scaled",1); cvsub(gray1s,gray2s, sub1); //subtract images cvsub(gray1s,sub1, imga1); cvsub(gray2s,sub1, imgb1); cvconvertscale(imga1, imga1u, 1.0, +32768 ); cvconvertscale(imgb1, imgb1u, 1.0, +32768 ); cvconvertscale(imga1u, imga, 1.0/256); cvconvertscale(imgb1u, imgb, 1.0/256); cvscalar d = cvavg(imgb, 0); //calculate average pixel intensity mean_b = d.val[0]; cvscalar e = cvavg(imga, 0); //calculate average pixel intensity mean_a = e.val[0]; printf("image pixel intensity = %f\n", mean_a); printf("image b pixel intensity = %f\n", mean_b); r = mean_a/mean_b; // ratio between average pixel intensities of image , b printf("r = %f\n", r); for( int = 0; < imgb1u->height; a++ ) //scale image b achieve same average pixel intensity image { for( int b = 0; b < imgb1u->width; b++ ) { cvscalar pixel = cvget2d(imgb1u, a, b); o = pixel.val[0]*r; cvscalar p; p.val[0] = o; cvset2d(imgb_mul, a, b, p); } } cvconvertscale(imgb_mul, imgbsc, 1.0/256); //convert 8 bit cvscalar c = cvavg(imgbsc, 0); //calculate average pixel intensity mean_b1 = c.val[0]; printf("image b intensity after scaling = %f\n", mean_b1); cvconvertscale(imgb_mul, imgb_scaled, 1.0, -32768); cvsub(imga1,imgb_scaled, sub2); //final subtraction calculte standard deviation cvconvertscale(sub2, sub2u, 1.0, +32768 ); cvconvertscale(sub2u, sub2_final, 1.0/256); cvscalar t,std; cvavgsdv(sub2_final, &t, &std); //calculate std deviation standard = std.val[0]; var = (standard*standard)/2; //square std deviation , devide 2 variance printf("variance camera noise = %f\n", var); cvshowimage("image a",imga); cvshowimage("image b scaled",imgbsc); cvshowimage("ccd noise",sub2); cvwaitkey(0); //to terminate images cvdestroywindow("ccd gain"); cvdestroywindow("image a"); cvdestroywindow("image b scaled"); cvreleaseimage(&img); cvreleaseimage(&img2); cvreleaseimage(&gray1); cvreleaseimage(&gray1s); cvreleaseimage(&gray2s); cvreleaseimage(&gray2); cvreleaseimage(&sub1); cvreleaseimage(&sub2); cvreleaseimage(&imga); cvreleaseimage(&imga1); cvreleaseimage(&imga1u); cvreleaseimage(&imgb); cvreleaseimage(&imgb1); cvreleaseimage(&imgb1u); cvreleaseimage(&imgb_mul); cvreleaseimage(&imgb_mull); cvreleaseimage(&imgbsc); cvreleaseimage(&imgb_scaled); cvreleaseimage(&sub2u); cvreleaseimage(&sub2_final); return 0; }
the results of program are:
image pixel intensity = 138.292328
image b pixel intensity = 253.836456
ratio = 0.544809
image b intensity after scaling = 138.351196
variance of ccd noise = 8.016509
i used different images presentation here put emphasis on supposed happen. in testing images closer (ratio around 0.992).
Comments
Post a Comment