ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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...
#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);
}
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
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.
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
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"
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...
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.
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?
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.