LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 03-31-2012, 05:42 AM   #106
jayshri
Member
 
Registered: Feb 2012
Posts: 71

Rep: Reputation: Disabled

hi firstfire,
thank u.... i gt it..
can u suggest me the modification in the code of median filter to make it adaptive weighed median filter???
thank u...

Last edited by jayshri; 04-03-2012 at 03:00 AM.
 
Old 04-03-2012, 03:03 AM   #107
jayshri
Member
 
Registered: Feb 2012
Posts: 71

Rep: Reputation: Disabled
here is the median filtering code.
Code:
#include<stdio.h>
#include<stdlib.h>
//#include"medianfilter.h"
#include<memory.h>
#include<math.h>

#define OUTPUT_FILE "out.bmp"

typedef char element;
long getImageInfo(FILE*,long,int);

// Median filtering
void _medianfilter( element* image,element* result,int nCols,int nRows)
{
	for(int m=1;m<nRows-1;++m)
		for(int n=1;n<nCols-1;++n)
		{
			int k=0;
			element window[9];
			for(int j=m-1;j<m+2;++j)
				for(int i=n-1;i<n+2;++i)
					window[k++]=image[j*nCols+i];
			for(int j=0;j<5;++j)
			{
				int min =j;
				for(int l=j+1;l<9;++l)
					if(window[l]<window[min])
						min=l;
				const element temp=window[j];
				window[j]=window[min];
				window[min]=temp;
				result[(m-1)*(nCols)+n-1]=window[4];
			}
		}
}

int main(int argc,char *argv[])
{

	FILE *bmpInput, *bmpOutput;
	unsigned char *pixel;
	char signature[2];
	long nRows,nCols,nbits;
	long xpixpeRm,ypixpeRm;
	long nColors;
	long fileSize;
	long vectorSize;
	long nBits;
	long rasterOffset;
	int i, j,k,l,m;
	unsigned char databuff[512][512][3];

	if(argc<2)
	{
		printf("Usage: %s <lena512.bmp>\n",argv[0]);
		exit(0);
	}

	//Open the specified input file for reading.
	printf("Reading %s ...\n",argv[1]);
	if((bmpInput = fopen(argv[1],"rb"))==NULL)
	{
		printf("Cannot read %s \n", argv[1]);
		exit(0);
	}

	//open output file.
	if((bmpOutput = fopen(argv[2],"w+"))==NULL)
	{
		if((bmpOutput = fopen(OUTPUT_FILE,"w+"))==NULL) //if user hasn't specified the output file use default output filename.
		{
			printf("Cannot read %s \n", argv[1]);
			exit(0);
		}
	}

	//position the pointer to the beginning of the file.
	fseek(bmpInput, 0L, SEEK_SET);

	//read First two characters of the input file.
	for(i=0; i<2; i++)
	{
		signature[i] = (char)getImageInfo(bmpInput,i,1);
	}

	//verify First two character of a BMP image file are BM
	if((signature[0]=='B') && (signature[1]=='M'))
	{
		printf("It is verified that the image is in Bitmap format\n");
	}
	else
	{
		printf("The image is not a BMP format,quitting....\n");
		exit(0);
	}

	//specifies number of bits per pixel in the image.
	nBits = getImageInfo(bmpInput, 28, 2);
	printf("The Image is \t%ld-bits per pixel. \n", nBits);

	//offset from the begining of the file where the pixel data starts.
	rasterOffset = getImageInfo(bmpInput,10,4);
	printf("The pixel Data is at \t%ld byte.\n",rasterOffset);

	//size of the file in bytes.
	fileSize=getImageInfo(bmpInput,2,4);
	printf("File size is \t%ld byte\n",fileSize);

	//number of columns in image.
	nCols = getImageInfo(bmpInput,18,4);
	printf("Width:\t\t%ld\n",nCols);

	//number of rows in image.
	nRows = getImageInfo(bmpInput,22,4);
	printf("Height:\t%ld\n",nRows);


	xpixpeRm = getImageInfo(bmpInput,38,4);
	printf("Image has \t%ld pixels per m in x-dir.\n",xpixpeRm);

	ypixpeRm = getImageInfo(bmpInput,42,4);
	printf("Image has \t%ld pixel per m in y-dir.\n",ypixpeRm);

	nColors = 1L<<nBits;
	printf("There are \t%ld number of colors \n",nColors);

	//it is the size of the array required to store the image pixel data.
	vectorSize = nCols*nRows;
	printf("vector Size is \t%ld\n",vectorSize);


	//write the bmp header to the output file.
	i = 0;
	while(i < rasterOffset)
	{
		fputc((char)getImageInfo(bmpInput, i, 1), bmpOutput);
		i++;
	}


	//now declare an 2D array to store & manipulate the image pixel data.
	pixel = (char *) malloc(sizeof(char)*nRows*nCols);

	//Set all the array value to zero.
	printf("\n\nResetting the pixel array: ");
	i = 0;
	while(i < vectorSize)
	{
		pixel[i] = 0x00;
		i++;
		// printf("%d ", i);
	}

	//Read the bitmap data into array:
	printf("\n\nReading the pixel array: ");
	i = 0;
	while(i < vectorSize)
	{
		//NOTE: Pixel array starts at rasterOffset!!!
		pixel[i] = (char)getImageInfo(bmpInput, rasterOffset + i, 1);
		i++;
		// printf("%d ", i);
	}

	//Display or modify pixel values:
	printf("\n\n Diplaying pixel values: \n\n");
	i = 0;
	j = 0;
	while(i < nRows)
	{
		j = 0;
		while(j < nCols)
		{
			printf("(%d,%d)-%02x\n ",i,j, pixel[i*nRows+j]); //Printing the pixel values.
			j++;
		}
		i++;
	}
	if((nRows!=512)||(nCols!=512)||(nBits!=8)){
		printf(" this works only for 512x512 8-color bitmaps\n");
		return 0;
	}

	_medianfilter( pixel, pixel, nCols, nRows);
	//write the modified pixel array to the output file.
	i = 0;
	while(i < vectorSize)
	{
		fputc(pixel[i], bmpOutput);
		i++;
	}

	//write the End-Of-File character the output file.
	fputc(EOF, bmpOutput);

	printf("\n");
	fclose(bmpInput);
	fclose(bmpOutput);
}

long getImageInfo(FILE* inputFile, long offset, int numberOfChars)
{
	unsigned char *ptrC;
	long value = 0L, temp;
	unsigned char dummy;
	int i;

	dummy = '0';
	ptrC = &dummy;

	//position the file pointer to the desired offset.
	fseek(inputFile, offset, SEEK_SET);

	//read the bytes into values (one byte at a time).
	for(i=0; i<numberOfChars; i++)
	{
		fread(ptrC,sizeof(char),1,inputFile);
		temp = *ptrC;
		value = (long) (value + (temp<<(8*i)));
	}

	return(value);
}
.
 
Old 04-03-2012, 03:26 AM   #108
firstfire
Member
 
Registered: Mar 2006
Location: Ekaterinburg, Russia
Distribution: Debian, Ubuntu
Posts: 709

Rep: Reputation: 428Reputation: 428Reputation: 428Reputation: 428Reputation: 428
Hi.

Sorry, I'm not familiar with this type of filtering.
 
Old 04-03-2012, 03:27 AM   #109
jayshri
Member
 
Registered: Feb 2012
Posts: 71

Rep: Reputation: Disabled
hi,
no problem.. thanx alot for ur help..
 
Old 04-10-2012, 05:43 AM   #110
jayshri
Member
 
Registered: Feb 2012
Posts: 71

Rep: Reputation: Disabled
i.m

Hi Firstfire,
I want to do only thresholding after reading a bmp image..can u give me some idea how to do that about the code????
Regards...
 
Old 04-10-2012, 08:26 AM   #111
firstfire
Member
 
Registered: Mar 2006
Location: Ekaterinburg, Russia
Distribution: Debian, Ubuntu
Posts: 709

Rep: Reputation: 428Reputation: 428Reputation: 428Reputation: 428Reputation: 428
Hi.

Do you mean this by thresholding?

If you know preferred value of the threshold in advance, then the following simple procedure should work
Code:
void thresholding1(pixel_t *in, pixel_t *out, int nx, int ny, int T )
{
	int i;
	for(i=0; i<nx*ny; i++)
		out[i] = (in[i]>=T)?255 : 0;
}
If the threshold value is unknown, here is an interative algorithm from Wikipedia (link above):
Code:
void thresholding2(pixel_t *in, pixel_t *out, int nx, int ny, int T )
{
	int i, n1, n2, Tprev, count=0;
	pixel_t G1,G2;

	do {
		G1 = G2 = 0;
		n1 = n2 = 0;
		Tprev = T;
		for(i=0; i<nx*ny; i++) {
			if( in[i]>=T ){
				n1++;
				G1+=in[i];
				out[i] = 255;
			}
			else {
				n2++;
				G2+=in[i];
				out[i] = 0;
			}
		}
		if(n1) G1 /= n1;
		if(n2) G2 /= n2;
		T = (G1+G2)/2;
		count++;
		printf("th. iteration %d: prev %d, cur %d\n", count, Tprev, T);
	} while(T != Tprev);
}
Hope that helps.

Last edited by firstfire; 04-10-2012 at 08:28 AM.
 
Old 04-10-2012, 09:18 AM   #112
jayshri
Member
 
Registered: Feb 2012
Posts: 71

Rep: Reputation: Disabled
hi first fire,
yup i mean that thresholding..actually i want to remove the small edges from the picture..so i want to do thresholding just after reading the image.. i don't want to do any kind of filtering or edge detection.. just thresholding after reading and writing the bmp file.. so how to call that thresholding function u have given in main function???
will the same code that u have gave me to read and write along with the canny edge detection work for thresholding if i comment out other parts???
thank u
 
Old 04-10-2012, 09:23 AM   #113
firstfire
Member
 
Registered: Mar 2006
Location: Ekaterinburg, Russia
Distribution: Debian, Ubuntu
Posts: 709

Rep: Reputation: 428Reputation: 428Reputation: 428Reputation: 428Reputation: 428
Call the code as follows:
Code:
thresholding2(bitmap_data, temp_image, ih.width, ih.height, 200);
It should work within the previous program.
 
Old 04-10-2012, 09:31 AM   #114
jayshri
Member
 
Registered: Feb 2012
Posts: 71

Rep: Reputation: Disabled
ok will try it,
but which value can i change nd check???
i mean which 1 is the upper nd lower threshold that i can manipulate?
 
Old 04-10-2012, 01:46 PM   #115
firstfire
Member
 
Registered: Mar 2006
Location: Ekaterinburg, Russia
Distribution: Debian, Ubuntu
Posts: 709

Rep: Reputation: 428Reputation: 428Reputation: 428Reputation: 428Reputation: 428
In both functions there is only one threshold. In the thresholding1() the threshold is the last argument. The second function thresholding2() tries to find an optimal threshold value and the last argument to it is the initial guess for the threshold.
 
Old 04-12-2012, 02:57 AM   #116
jayshri
Member
 
Registered: Feb 2012
Posts: 71

Rep: Reputation: Disabled
hi first fire,
thanx alot for your help...
itz doing thresholding but i want to remove the max no. of noise so that the object become clearly visible and that the back ground become totally white...
i have this imagehttp://www.google.co.in/imgres?um=1&...9,r:8,s:0,i:82
can u suggest me the changes needed in the previous algorithm so that the black object remains and all the small particles excpt the object(black particles) can be removed upto some extent by thresholding???
thank u
 
Old 04-12-2012, 05:37 AM   #117
firstfire
Member
 
Registered: Mar 2006
Location: Ekaterinburg, Russia
Distribution: Debian, Ubuntu
Posts: 709

Rep: Reputation: 428Reputation: 428Reputation: 428Reputation: 428Reputation: 428
Hi.

If you need to inverse the image, then exchange 255 and 0 in assignments out[i]=....
 
Old 04-12-2012, 06:35 AM   #118
jayshri
Member
 
Registered: Feb 2012
Posts: 71

Rep: Reputation: Disabled
hi first fire..
Quote:
i dnt need a a invert image ... what i mean is that the picture in the link i have given u the "black clusters" are the nano particles and the gray backgroung behind those black nano particles i want to make it whole white by thresholding... becuase when the edge is detected alond with that black dots the edges of the gray backgroung also appears due to which itz a bit difficult to point out those dots.
Quote:
so if i do thresholding then i can remove those gray backgroung by comparing the intensity of the dots with the intensity of that gray backgroung..so it will become white..in this way i will b able to remove a minimum amount of noisy edges so edge detection will b clear.
bt the alogithm that u have given for thresholding2().. i have changes the para meter"
Quote:
thresholding2(bitmap_data, temp_image, ih.width, ih.height, 200);
to 255,300.. itz giving same o/p.
i want a image like this...here object are white and the background is almost black..... i have done it in gimp..
but what are the modification need in the code to get an image like this after thresholding????
thank u...

Last edited by jayshri; 04-13-2012 at 01:43 AM.
 
Old 04-12-2012, 02:04 PM   #119
firstfire
Member
 
Registered: Mar 2006
Location: Ekaterinburg, Russia
Distribution: Debian, Ubuntu
Posts: 709

Rep: Reputation: 428Reputation: 428Reputation: 428Reputation: 428Reputation: 428
Quote:
Originally Posted by jayshri View Post
bt the alogithm that u have given for thresholding2().. i have changes the para meter" to 255,300.. itz giving same o/p.
thresholding2() tries to figure out an "optimal" value for the threshold using given value only as an initial guess. Apparently, this "optimal" value is bad for your purposes. You still can use the thresholding1() function and figure out suitable threshold value by hand. For image you linked above it is about 65.
 
Old 04-12-2012, 02:23 PM   #120
firstfire
Member
 
Registered: Mar 2006
Location: Ekaterinburg, Russia
Distribution: Debian, Ubuntu
Posts: 709

Rep: Reputation: 428Reputation: 428Reputation: 428Reputation: 428Reputation: 428
By the way, here are modified versions of save_bmp() and load_bmp() which take into account padding requirement of BMP standard:
Code:
pixel_t *load_bmp(char *filename, BITMAPINFOHEADER *bitmapInfoHeader)
{
	FILE *filePtr; //our file pointer
	struct bmpfile_magic  mag;
	struct bmpfile_header bitmapFileHeader; //our bitmap file header
	pixel_t *bitmapImage;  //store image data

	filePtr = fopen(filename,"r");
	if (filePtr == NULL)
	{
		perror("fopen()");
		exit(1);
	}

	fread(&mag, sizeof(struct bmpfile_magic),1,filePtr);
	//verify that this is a bmp file by check bitmap id
	if ( *((uint16_t*) mag.magic) != 0x4D42 )
	{
		fprintf(stderr, "Not a BMP file: magic=%c%c\n", mag.magic[0], mag.magic[1]);
		fclose(filePtr);
		return NULL;
	}
	//read the bitmap file header
	fread(&bitmapFileHeader, sizeof(struct bmpfile_header), 1, filePtr);

	//read the bitmap info header
	fread(bitmapInfoHeader, sizeof(BITMAPINFOHEADER), 1, filePtr);

	if( bitmapInfoHeader->compress_type != 0)
		fprintf(stderr, "Warning, compression is not supported.\n");

	//move file point to the beginning of bitmap data
	fseek(filePtr, bitmapFileHeader.bmp_offset, SEEK_SET);

	//allocate enough memory for the bitmap image data
	bitmapImage = (pixel_t *)malloc(bitmapInfoHeader->bmp_bytesz*(sizeof(pixel_t)));

	//verify memory allocation
	if (!bitmapImage)
	{
		free(bitmapImage);
		fclose(filePtr);
		return NULL;
	}

	//read in the bitmap image data
	unsigned long i, j, pad, count=0;
	unsigned char c;
	pad = 4*ceil(bitmapInfoHeader->bitspp*bitmapInfoHeader->width/32.) - bitmapInfoHeader->width;
	for(i=0; i<bitmapInfoHeader->height; i++){
		for(j=0; j<bitmapInfoHeader->width; j++){
			fread(&c, sizeof(unsigned char), 1, filePtr);
			bitmapImage[count++] = (pixel_t) c;
		}
		fseek(filePtr, pad, SEEK_CUR);  // skip padding bytes
	}

	//close file and return bitmap image data
	fclose(filePtr);
	return bitmapImage;
}

// Return: nonzero on error.
int save_bmp(char *filename, BITMAPINFOHEADER *bmp_ih, pixel_t *data)
{
	unsigned long ncolors = 1<<bmp_ih->bitspp;  // always use full palette
	unsigned int offset =
		sizeof(struct bmpfile_magic)
		+ sizeof(struct bmpfile_header)
		+ sizeof(BITMAPINFOHEADER)
		+ ncolors*4;

	struct bmpfile_header bmp_fh = {
		.filesz = offset + bmp_ih->bmp_bytesz,
		.creator1 = 0,
		.creator2 = 0,
		.bmp_offset = offset
	};

	FILE* fp = fopen(filename,"w");
	if (fp == NULL) return 1;
	struct bmpfile_magic mag = {{0x42, 0x4d}};

	fwrite(&mag, 1, sizeof(struct bmpfile_magic), fp);
	fwrite(&bmp_fh, 1, sizeof(struct bmpfile_header), fp);
	fwrite(bmp_ih, 1, sizeof(BITMAPINFOHEADER), fp);

	// Palette
	rgb_t color = {0, 0, 0, 0};
	unsigned long i, j, pad;
	for(i=0; i < ncolors; i++)
	{
		color.r = i;
		color.g = i;
		color.b = i;
		fwrite(&color, 1, sizeof(rgb_t), fp);
	}

	// We use int instead of uchar, so we can't write img in 1 call any more.
	//fwrite(data, 1, bmp_ih->bmp_bytesz, fp);
	unsigned char c;

	pad = 4*ceil(bmp_ih->bitspp*bmp_ih->width/32.) - bmp_ih->width;

	for(i=0; i < bmp_ih->height; i++) {
		for(j=0; j < bmp_ih->width; j++) {
			c = (unsigned char) data[j + bmp_ih->width*i];
			fwrite(&c, sizeof(char), 1, fp);
		}
		c = 0;
		for(j=0; j<pad; j++)
			fwrite(&c, sizeof(char), 1, fp);
	}

	fclose(fp);
	return 0;
}
For example your abovementioned image is 341x283 pixels, 8 bits per pixel (and it happen to have only 207 colors instead of full 256 colors after converting to bmp, but that is another story). According to BMP specification, the size of each row of pixels should be a multiple of 4 bytes. 341/4 = 85.25, therefore we need 86*4-341=3 bytes of padding, so that each row contain 86*4=344 bytes. In contrast, for 512x512x8 (beloved lena) image we have 512/4=128, so no padding needed.

P.S. Why don't you use something like imlib2 to load/save images? There should be lots of libraries to perform image processing also. Or command line utilities like convert from imagemagick package?

Last edited by firstfire; 04-12-2012 at 02:29 PM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Applying median filter to a picture ... tomazN Programming 7 04-03-2006 05:15 AM
Minolta MC 2300dl + foo2zjs driver = color images printed in black? J_Szucs Linux - Hardware 1 02-06-2006 02:30 AM
What are the color code ? cigarstub Linux - Networking 5 10-22-2005 10:51 AM
how to draw color images with xlib? BBB Programming 19 07-15-2005 02:04 PM
filter the code Xiangbuilder Programming 7 10-23-2003 07:28 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:07 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration