SlideShare a Scribd company logo
Project Report
Edge Detection and median filtering for colour JPEG images
By: Farhad Gholami
EE8220: Advanced Digital Filters
April 2013
1
Table of Contents
Introduction :...........................................................................................................................................................................3
Gradient : ................................................................................................................................................................................3
Image gradient : ......................................................................................................................................................................3
Sobel Algorithm : ....................................................................................................................................................................4
JPEG Overview ........................................................................................................................................................................5
JPEG Images processing software : ........................................................................................................................................6
Median Filter ...........................................................................................................................................................................7
2D median filter: .....................................................................................................................................................................7
Sorting algorthm: ....................................................................................................................................................................7
Setting up Compile and Linker : ..............................................................................................................................................8
Appendix A: Install open source JPEG library for VisualStudio...............................................................................................10
JPEG Library construction steps:............................................................................................................................................10
Appendix B: Source code.......................................................................................................................................................11
2
Introduction :
JPEG is a widely used standard to compress digital images and bbject detection using edges is a common task in
machine vision and there are algorithms to highlight the edges of the objects using a mathematical operator to achieve
this task .
In this project we will introduce a “Sobel edge detection” algorithm working on JPEG colour images and also introduce a
median filter implementation to reject impulsive noise. We use a PC running Windows7 for our development .Source code
is in C and IDE is MSVisualStudio10.
Digital Image:
A (digital) color image is includes color information for each pixel.For visually acceptable results, it is necessary to provide
three values(color channels) for each pixel. The RGB color space is commonly used in computer displays.A color image
has three values per pixel and they measure the intensity and chrominance of light. The actual information stored in the
digital image data is the brightness information in each spectral band. Eight bits per sample (3x8=24 bits per pixel) is
adequate for most applications.
Gradient :
The gradient of a scalar field points in the direction of the greatest rate of increase of the scalar field, and whose
magnitude is that rate of increase. In simple terms, the variation in space of any quantity can be represented (e.g.
graphically) by a slope. The gradient represents the steepness and direction of that slope.
In below two images, the scalar field is in black and white, black representing higher values, and its corresponding gradient
is represented by blue arrows.
The gradient at a point is a vector pointing in the direction of the steepest slope at that point. The steepness of the slope at
any point is given by the magnitude of the gradient vector
Image gradient :
Mathematically, the gradient of a two-variable function (here the image intensity function) at each image point is a 2D vector
with the components given by the derivatives in the horizontal and vertical directions.
At each image point, the gradient vector points in the direction of largest possible intensity increase, and the length of the
gradient vector corresponds to the rate of change in that direction.
Since the intensity function of a digital image is only known at discrete points, derivatives of this function cannot be defined
unless we assume that there is an underlying continious intensity function which has been sampled at the image points.
With some additional assumptions, the derivative of the continuous intensity function can be computed as a function on the
3
sampled intensity function, i.e., the digital image. It turns out that the derivatives at any particular point are functions of the
intensity values at virtually all image points. However, approximations of these derivative functions can be defined at lesser
or larger degrees of accuracy.
Sobel Algorithm :
The Sobel operator represents a rather inaccurate approximation of the image gradient, but is still of sufficient quality to be
of practical use in many applications. More precisely, it uses intensity values only in a 3×3 region around each image point
to approximate the corresponding image gradient, and it uses only integer values for the coefficients which weight the
image intensities to produce the gradient approximation.
Mathematically, the sobel uses two 3×3 kernels which are convolved with the original image to calculate approximations
of the derivatives - one for horizontal changes, and one for vertical as below shows:
The operator uses two 3×3 kernels which are convolved with the original image to calculate approximations of the
derivatives - one for horizontal changes, and one for vertical. If we define A as the source image, and Gx and Gy are two
images which at each point contain the horizontal and vertical derivative approximations, the computations are as follows:
4
Below is algorithm implemented in C:
JPEG Overview
JPEG (Joint Photographic Experts Group) [ISO] is a compression scheme to reduce the size of continuous-tone digital
images. It is particularly useful to save space on storage devices, where compression ratio and image quality are more
important than compression speed or delay. Many of those applications use JPEG or a related image compression method.
JPEG lossy process is based on the Discrete Cosine Transform (DCT). It packs the transformed data in sequential order,
using zero suppression in combination with Huffman symbol coding. We will focus on the IDCT related steps to show where
our improvements apply.
5
JPEG Images processing software :
Pixels are points in a graphical image and colour channels being used to show relative intensity. For example Gray scale
has 1 channel and RGB have 3 channels for each pixel. Size of an image contains three dimensions: width, height,
channels(3 for RGB).
To use JPEG image read and write functions in our c code , we use open source libjpeg library which implements
decoding and encoding functions and utilities for handling JPEG images. This library is maintained by the Independent
JPEG Group (IJG). For example this is how we read an image file:
Appendix-A includes information for compile and setting up this library.
6
Median Filter
Neighbourhood averaging can suppress isolated out-of-range noise, but the side effect is that it also blurs sudden changes
(corresponding to high spatial frequencies) such as sharp edges.
The median filter is an effective method that can suppress isolated noise without blurring sharp edges. Specifically, the
median filter replaces a pixel by the median of all pixels in the neighbourhood:
2D median filter:
The window of a 2D median filter can be of any central symmetric shape. The pixel at the center will be replaced by the
median of all pixel values inside the window.
Sorting algorthm:
Sorting is necessary for finding the median of a set of values. Various sorting algorithm with complexity of O(n log2
n)However in this case, assuming the number of pixels is quite limited, a simple sorting method with complexity )(n**2) can
be used. The code segment below sorts an array of k elements:
Below diagram illustrates how different tools take various input files and generate appropriate output files to ultimately be
used in building an executable image. mpi.lib and jpeg.lib libraries will be added to final image using linker.
7
Setting up Compile and Linker :
Below pictures shows how to set up IDE and other details:
8
I
9
Appendix A: Install open source JPEG library for VisualStudio
First we need to download jpeg free library from here : http://www.ijg.org/
Library makefile builds the IJG library as a static Win32 library, and optional application make files builds the sample
applications as Win32 console applications. (building the applications lets us run the self-test.)
Provided make files we used work as project files in Visual Studio 2010 or later.
JPEG Library construction steps:
1. Open the command prompt, change to the main directory and execute the
command line NMAKE /f makefile.vc setup-v10
This will move jconfig.vc to jconfig.h and makefiles to project files. (Note that the renaming is critical!)
2. Open the solution file jpeg.sln, build the library project. (If you are using Visual Studio more recent than 2010 (v10),
you'll probably get a message saying that the project files are being updated.)
3. Open the solution file apps.sln, build the application projects.
4. To perform the self-test, execute the command line : NMAKE /f makefile.vc test-build
5. Move the application .exe files from `app`Release to an appropriate location on your path.
Below pictures shows how to configure and install the IJG software for MS-VC++ 2010 Developer Studio :
10
Note: You might need to installing Windows SDK if your host dose not have win32.mak file.
Appendix B: Source code
// jpeg_io.c
//
// Revision History
// ----------------
//
// F. Gholami 2013-04-12 - Original
11
//
//
// Description:
// ------------------
// JPEG related APIs
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <setjmp.h>
#include "jpeg_io.h"
image_s *image_outline_new(int h, int w, int c);
void image_write_JPEG_file (char *filename , image_s *image , int quality)
{
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE * outfile ; // target file
JSAMPROW row_pointer[1]; // pointer to JSAMPLE row[s]
int row_stride; // physical row width in image buffer
printf("image_write_JPEG_file: starts n");
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
// Step 2: specify destination file
//printf("image_write_JPEG_file: step2 specify destination filen");
if ((outfile = fopen ( filename , "wb"))== NULL )
{
fprintf(stderr , "JPEG_WRITE_ERROR : can't open %s/n", filename);
exit(1);
}
jpeg_stdio_dest(&cinfo ,outfile);
// Step 3: set parameters for compression
//printf("image_write_JPEG_file: step3 set parameters for compressionn");
cinfo.image_width = image->width; // image width and height, in pixels
cinfo.image_height = image->height;
cinfo.input_components = image->components; // #components per pixel
if((image->components) == 3)
{
cinfo.in_color_space = JCS_RGB; // colorspace of input image
}
else
{
cinfo.in_color_space = JCS_GRAYSCALE; // colorspace of input image
}
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, quality, TRUE); // limit baseline-JPEG values
// Step 4: Start compressor
12
//printf("image_write_JPEG_file: step4 Start compressorn");
jpeg_start_compress(&cinfo, TRUE);
// Step 5: while (scan lines remain to be written)
//printf("image_write_JPEG_file: step5 while (scan lines remain to be written)n");
row_stride = image->width * image->components;
while (cinfo.next_scanline < cinfo.image_height)
{
row_pointer[0] = image->buffer[cinfo.next_scanline];
(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
// Step 6: Finish compression
//printf("image_write_JPEG_file: step6 Finish compressionn");
jpeg_finish_compress (&cinfo);
fclose (outfile);
// Step 7: release JPEG compression object
//printf("image_write_JPEG_file: step7 release JPEG compression object n");
printf("image_write_JPEG_file: release JPEG compression object n");
jpeg_destroy_compress(&cinfo);
}
//=======================================================
// Error stuff - copy&paste
void my_error_exit (j_common_ptr cinfo)
{
// cinfo->err really points to a my_error_mgr struct, so coerce pointer
my_error_ptr myerr = (my_error_ptr) cinfo->err;
// Always display the message.
// We could postpone this until after returning, if we chose.
(*cinfo->err->output_message) (cinfo);
// Return control to the setjmp point
longjmp(myerr->setjmp_buffer, 1);
}
//==============================================================
image_s *image_read_JPEG_file(char *filename)
{
struct jpeg_decompress_struct cinfo;
struct my_error_mgr jerr;
// More stuff
FILE *infile; //source file
JSAMPARRAY buffer; // Output row buffer */
int row_stride; // physical row width in output buffer */
int current_row = 0;
image_s *image;
// printf("image_read_JPEG_file: step0 reading JPEG file n");
if ((infile=fopen(filename , "rb")) ==NULL)
13
{
fprintf (stderr , "image_read_JPEG_file: cant open %sn" , filename);
return 0;
}
fprintf (stderr , "image_read_JPEG_file: opened %sn" , filename);
// Step 1: allocate and initialize JPEG decompression object */
printf("image_read_JPEG_file: step1 allocate/init JPEG decompress objectn");
cinfo.err = jpeg_std_error (&jerr.pub);
jerr.pub.error_exit = my_error_exit;
if (setjmp(jerr.setjmp_buffer) )
{
jpeg_destroy_decompress(&cinfo);
fclose (infile);
printf("image_read_JPEG_file: step1 ... exit!!!n");
return 0;
}
// Now we can initialize the JPEG decompression object. */
//printf("image_read_JPEG_file: decompress starts...n");
jpeg_create_decompress (&cinfo);
//printf("image_read_JPEG_file: decompress ends...n");
// Step 2: specify data source file */
//printf("image_read_JPEG_file: step2 specify data source filen");
jpeg_stdio_src (&cinfo,infile);
// Step 3: read file parameters with jpeg_read_header()
//printf("image_read_JPEG_file: step3 read file parametersn");
(void)jpeg_read_header (&cinfo ,TRUE);
// Step 5: Start decompressor
//printf("image_read_JPEG_file: step4 Start decompressor n");
(void) jpeg_start_decompress(&cinfo);
// Step 5 1/2 init image_s object
//printf("image_read_JPEG_file: step5 init image_s objectn");
image = image_outline_new( cinfo.output_height, cinfo.output_width,
cinfo.output_components);
row_stride = cinfo.output_width * cinfo.output_components;
buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo,
JPOOL_IMAGE, row_stride, 1);
// Step 6: while (scan lines remain to be read) */
// jpeg_read_scanlines(...);
//printf("image_read_JPEG_file: step6 scan lines remain to be readn");
while (cinfo.output_scanline < cinfo.output_height)
{
(void) jpeg_read_scanlines(&cinfo, buffer, 1);
// Assume put_scanline_someplace wants a pointer and sample count. */
put_scanline_in_image_s(buffer[0], image, row_stride, current_row++);
}
// Step 7: Finish decompression */
14
//printf("image_read_JPEG_file: step7 finish decompression");
(void)jpeg_finish_decompress(&cinfo);
// Step 8: Release JPEG decompression object */
// printf("image_read_JPEG_file: step8 release JPEG decompression objectn");
jpeg_destroy_decompress(&cinfo);
fclose (infile);
return image;
}
//=======================================================================
image_s *image_outline_new(int h, int w, int c)
{
image_s *new;
int i;
//printf("image_outline_new:starts , create image h=%d, w=%d c=%d n", h,w,c);
new = malloc(sizeof(image_s));
if(new == NULL)
{
fprintf(stderr, "image_outline_new: ERROR.. Out of memoryn");
exit(1);
}
new->buffer = malloc(sizeof(JSAMPLE *)*(h+2));
if(new->buffer == NULL)
{
fprintf(stderr, "image_outline_new: ERROR.. Out of memoryn");
exit(1);
}
new->buffer[0] = calloc(sizeof(JSAMPLE),(w+2)*c*(h+2));
if(new->buffer[0] == NULL)
{
fprintf(stderr, "image_outline_new: ERROR... Out of memoryn");
exit(1);
}
new->buffer[0] = new->buffer[0]+c;
new->buffer = new->buffer + 1;
for(i = 0; i <= h; i++)
{
new->buffer[i] = new->buffer[i-1]+(w+2)*c;
}
new->height = h;
new->width = w;
new->components = c;
printf("image_outline_new: ends...n");
return new;
}
//===================================================================================
image_s *image_new(int h, int w, int c)
{
15
image_s *new;
int i ;
printf("image_new:starts , create image h=%d, w=%d c=%d n", h,w,c);
new = malloc(sizeof(image_s));
new->buffer = malloc(sizeof(JSAMPLE *)*h);
if(new->buffer == NULL)
{
fprintf(stderr, "image_new: Out of memory!n");
exit(1);
}
new->buffer[0] = malloc(sizeof(JSAMPLE)*w*c*h);
if(new->buffer[0] == NULL)
{
fprintf(stderr,"image_new: Out of memory!n");
exit(1);
}
for(i=1; i<h; i++)
{
new->buffer[i] = new->buffer[i-1]+w*c;
}
new->height = h;
new->width = w;
new->components = c;
printf("image_new: h=%d, w=%d c=%d n", h,w,c);
printf("image_new: ends okn");
return new;
}
//=====================================================================
void put_scanline_in_image_s(JSAMPROW buffer,image_s *image,
int row_stride,int current_row)
{
memcpy(image->buffer[current_row],buffer, sizeof(JSAMPLE)*row_stride);
}
//=====================================================================
// main.c
//
// Revision History
// ----------------
//
// F. Gholami 2012-03-29 - Original
//
//
// Description:
// ------------------
// Main file for parallel soble edge detection
//
#include <string.h>
#include <stdlib.h>
#include "mpi.h"
#include "jpeg_io.h"
16
#include "mpi_decomp.h"
#include "sobel_filter.h"
#define FILE_NAME_SIZE 2048
#define JPEG_QUALITY 20
#define DIMENSION_SIZE_2D 2
#define SPRINTF_BUFFER_SIZE 256
int main(int argc,char **argv)
{
image_s *im, *new_im ;
int sx,sy,ex,ey;
int sobel = TRUE;
int currentarg = 1;
char outfilename[FILE_NAME_SIZE];
int outn;
// MPI variables
int rank, rank2d; // Processor rank
int numtasks; // No. of Processors
MPI_Datatype MPI_Pixel;
MPI_Datatype MPI_Image_block;
MPI_Status status;
int *displ;
int i,j,k,ix;
MPI_Comm comm2d;
int nbr_left, nbr_right, nbr_up, nbr_down;
int dims[DIMENSION_SIZE_2D], periods[DIMENSION_SIZE_2D], coords[DIMENSION_SIZE_2D],
block[DIMENSION_SIZE_2D];
double startwtime = 0.0, endwtime;
char processor_name[MPI_MAX_PROCESSOR_NAME];
int namelen;
//MPI_Init
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &numtasks);
MPI_Get_processor_name(processor_name,&namelen);
fprintf(stdout,"Process %d of %d is on %sn",
rank, numtasks, processor_name);
fflush(stdout);
if(rank == 0) //master node
{
startwtime = MPI_Wtime();
fprintf(stdout,"main: start time=%lf secn", startwtime );
}
// default out filelename
17
outn =sprintf_s (outfilename,256 , "%s" ,argv [argc-1]);
sprintf_s(outfilename + outn,256,"_out.jpg");
printf("nmain: processor[%d] is aliven", rank);
// Parse argv
while(currentarg < argc-1)
{
if(0 == strcmp(argv[currentarg], "-o"))
{
currentarg++;
sprintf_s(outfilename ,2048, "%s", argv[currentarg]);
}
currentarg++;
}
if(argc-currentarg ==1)
{
fprintf(stderr, "usage: %s [-1D][-sjpj-l n][-o outfile] filenamen", argv[0]);
}
// Read JPEG file(JPEG)
printf("nRead JPEG file starts ....n");
im = image_read_JPEG_file ("C:/book/testimg.jpg");
if(rank == 0)
{
printf("main: Image loaded in memory=%lf secn", MPI_Wtime());
}
printf("main: Proc[%d], image->w=%d image->h=%d image->c=%d n",
rank, im->width, im->height, im->components);
// MPI 2D Decomposition create
dims[0] = 0;
dims[1] = 0;
periods[0] = FALSE;
printf("main: MPI decomp2d creat ...n");
MPI_Dims_create(numtasks, DIMENSION_SIZE_2D, dims);
printf("main: MPI_COMM_WORLD starts ...n");
MPI_Cart_create(MPI_COMM_WORLD, DIMENSION_SIZE_2D, dims, periods, TRUE, &comm2d);
MPI_Comm_rank(comm2d, &rank2d);
// MPI 2-d Decomposition init
printf("main: Matrix 2D decomp init starts ...n");
matrix_2D_neighbors(comm2d, &nbr_up, &nbr_down,
&nbr_left, &nbr_right);
printf("main: Proc[%d], 2D-id=%d up=%d down=%d left=%d right=%dn",
rank, rank2d, nbr_up, nbr_down, nbr_left, nbr_right);
//matrix-decomposition
printf("main: Matrix 2D decomp starts ...n");
matrix_2D_decomp( comm2d, im->width, im->height, im->components,
&sx, &ex, &sy,&ey, block );
18
printf("main: Proc[%d], x:<%d,%d> y:<%d,%d> b:<%d,%d>n",
rank2d, sx,ex, sy,ey, block[0],block[1]);
printf("main:Proc[%d], edge detection starts n",rank2d);
// edge detection
if(rank2d == 0)
{
new_im = image_new (block[1]*dims[1], block[0]*dims[0], im->components);
new_im->width = im->width;
new_im->height = im->height;
}
else
{
new_im = image_new(block[1], block[0], im->components);
}
if(rank2d == 0)
printf("main: Decomp fisnished at:%lf sn", MPI_Wtime());
for(ix=0;ix<1000;ix++) //to increase computional load
sobel_filtering(im,new_im, sx,ex,sy,ey);
printf("main:Sobel end n");
// Gather data
printf("main: MPI Gather data...n");
MPI_Type_contiguous(im->components*sizeof(JSAMPLE), MPI_BYTE, &MPI_Pixel);
MPI_Type_commit(&MPI_Pixel);
if(rank2d == 0) //for master node
{
MPI_Type_vector (block[1] ,block[0], block[0]*dims[0] ,MPI_Pixel ,&MPI_Image_block);
MPI_Type_commit (&MPI_Image_block);
displ = safe_malloc (sizeof(int)*numtasks);
for(i=0,k=0; i < dims[0];i++)
{
for(j=0; j<dims[1];j++,k++)
{
displ[k] = ( (j*block[1]*dims[0]) + i) * (block[0]*im->components) ;
printf("main: Proc[%d], displ[%d] = %dn", rank2d ,k, displ[k]);
}
}
} //rank2d==0
else//rank2d!=0 slave nodes
{
printf("main:Proc[%d],...mpi vectorn", rank2d);
MPI_Type_vector(block[1],block[0],block[0],MPI_Pixel, &MPI_Image_block);
MPI_Type_commit(&MPI_Image_block);
}
if(rank2d == 0) //in master mode
{
printf("main: MPI_Recv...n");
for(i = 1; i < numtasks; i++)
{
MPI_Recv(new_im->buffer[0]+displ[i], 1, MPI_Image_block, i,100,comm2d,&status);
19
printf("main: Proc[0] recieved Image block from %d", i);
}
}
else //in slav nodes
{
printf("main: MPI_Send...n");
MPI_Send(new_im->buffer[0],1,MPI_Image_block,0,100,comm2d);
}
printf("main: Proc[%d],Gather ... Donen", rank2d);
// write output
printf("main: write output...");
if(rank2d == 0)
{
image_write_JPEG_file(outfilename, new_im ,JPEG_QUALITY);
endwtime = MPI_Wtime();
printf("wall clock time = %fn", endwtime-startwtime);
}
//MPI_Finish
MPI_Type_free(&MPI_Image_block);
MPI_Type_free(&MPI_Pixel);
MPI_Comm_free(&comm2d);
MPI_Finalize();
printf("n");
}
// mpi_decomp.c
//
// Revision History
// ----------------
//
// F. Gholami 2013-04-12 - Original
//
//
// Description:
// ------------------
// Test of MPI/MPE decomp of matrix for parallel soble edge detection
#include "mpi_decomp.h"
//----------------------------------------------------------------------------
// matrix_2D_neighbors
// This routine show the neighbors in a 2-d decomposition of
// the domain. This assumes that MPI_Cart_create has already been called
//--------------------------------------------------
void matrix_2D_neighbors(MPI_Comm comm, int *nbr_up, int *nbr_down,
int *nbr_left, int *nbr_right)
{
printf("matrix_2D_neighbors: starts ...n");
MPI_Cart_shift(comm,0,1, nbr_left, nbr_right);
MPI_Cart_shift(comm,1,1, nbr_up, nbr_down);
}
//-----------------------------------------------------
20
// matrix_2D_decomp
// This routine computes the decomposition
//---------------------------------------------------------
void matrix_2D_decomp(MPI_Comm comm, int nodes_x, int nodes_y, int comp,
int *start_x, int *end_x,int *start_y, int *end_y,int *block)
{
int dims[2];
int coords[2];
int periods[2];
printf("matrix_2D_decomp: starts ...n");
MPI_Cart_get( comm, 2, dims, periods, coords);
block[0] = (nodes_x / dims[0]) +1;
if(nodes_x % dims[0] == 0)
{
block[0]--;
}
block[1] = ( nodes_y / dims[1] + 1) ;
if((nodes_y % dims[1]) == 0)
{
block[1]--;
}
*start_x = coords[0] * block[0];
*end_x = min( (coords[0]*block[0]+block[0]) , nodes_x) - 1;
*start_y = coords[1]*block[1];
*end_y = min( coords[1]*block[1]+block[1]-1 , nodes_y-1) ;
}
// mylib.c
//
// Revision History
// ----------------
//
// F. Gholami 2012-11-22 - Original
//
//
// Description:
// ------------------
// Auxiliarry functions for parallel soble edge detection
//
#include "mylib.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#define OUT_OF_MEMORY "Out of memoryn"
void *safe_malloc(size_t size)
{
void *new;
new = malloc(size);
21
if(new == NULL)
{
fprintf(stderr, OUT_OF_MEMORY);
exit(1);
}
return new;
}
void *safe_calloc(size_t nelem, size_t elsize)
{
void *new;
new = calloc(nelem,elsize);
if(new == NULL)
{
fprintf(stderr, OUT_OF_MEMORY);
exit(1);
}
return new;
}
void error_print_end(char *s)
{
fprintf(stderr, s);
exit(1);
}
// sobel_filter.c
//
// Revision History
// ----------------
//
// F. Gholami 2013-04-18 - Original
//
//
// Description:
// ------------------
// Image spatial filter
//
#include "Sobel_filter.h"
// Spatial filtering of image data */
// Sobel filter (horizontal differentiation
// Input: image1[y][x] ---- Outout: image2[y][x]
// Definition of Sobel filter in horizontal direction */
// int weight[3][3] = {{ -1, 0, 1 },
// { -2, 0, 2 },
// { -1, 0, 1 }};
22
//sobel operator
void sobel_filtering(image_s *im, image_s *new_im,
int sx, int ex, int sy,int ey)
{
int i,j,k;
int x,y,sum;
JSAMPLE **buf;
buf = im->buffer;
k = im->components;
for(i = sy; i<ey+1; i++)
for(j = sx*k;j < (ex+1)*k; j++)
{
x = buf[i+1][j-k]+2*buf[i+1][j]+buf[i+1][j+k]- (buf[i-1][j-k]+2*buf[i-1][j]+buf[i-1][j+k]);
y = buf[i-1][j+k]+2*buf[i][j+k]+buf[i+1][j+k]- (buf[i-1][j-k]+2*buf[i][j-k]+buf[i+1][j-k]);
sum = abs(x/4) + abs(y/4);
if(sum > 255) //255 = 0xff
sum = 255;
new_im->buffer[i-sy][j-(sx*k)] = sum;
}
}
// jpeg_io.h
//
// Revision History
// ----------------
//
// F. Gholami 2013-04-12 - Original
//
//
// Description:
// ------------------
// JPEG related APIs header
//
#ifndef JPEG_IO_H
#define JPEG_IO_H
#include <stdio.h>
#include <setjmp.h>
#include "jpeglib.h"
#define TRUE 1
#define FALSE 0
typedef struct jpeg_compress_struct jpeg_com_struct;
typedef struct jpeg_decompress_struct jpeg_decom_struct;
struct image_s
{
JSAMPLE **buffer;
int height;
int width;
int components;
};
23
typedef struct image_s image_s;
//->
struct my_error_mgr
{
struct jpeg_error_mgr pub; // "public" elds
jmp_buf setjmp_buffer; // for return to caller
};
typedef struct my_error_mgr * my_error_ptr;
void image_write_JPEG_file (char *filename,image_s *iamge,int quality);
image_s *image_read_JPEG_file (char * filename);
image_s *image_new (int h, int w, int c);
void put_scanline_in_image_s (JSAMPROW buffer, image_s *image,
int row_stride,int current_row);
#endif
// mpi_decomp.h
//
// Revision History
// ----------------
//
// F. Gholami 2013-04-16 - Original
//
//
// Description:
// ------------------
// Header file for image filter
//
#ifndef MATRIX_DECOMP_H
#define MATRIX_DECOMP_H
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
#include "mylib.h"
#define TRUE 1
#define FALSE 0
// matrix_2D_neighbors: This routine show the neighbors in a 2D decomposition of
// the domain. This assumes that MPI_Cart_create has already been called
void matrix_2D_neighbors(MPI_Comm comm, int *nbr_up,
int *nbr_down, int *nbr_left, int *nbr_right);
// matrix_2D_decomp : This routine computes the decomposition
void matrix_2D_decomp(MPI_Comm comm, int nodes_x, int nodes_y, int comp,
int *start_x, int *end_x, int *start_y, int *end_y, int *block);
#endif
// mylib.h
//
24
// Revision History
// ----------------
//
// F. Gholami 2013-04-16 - Original
//
//
// Description:
// ------------------
// Auxiliarry functions for parallel soble edge detection
//
#ifndef MYLIB_H
#define MYLIB_H
#include <stdlib.h>
#include <stdio.h>
void *safe_malloc(size_t size);
void *safe_calloc(size_t nelem, size_t elsize);
#endif
// sobel_filter.h
//
// Revision History
// ----------------
//
// F. Gholami 2013-04-18 - Original
//
//
// Description:
// ------------------
// Image filter header file for parallel soble edge detection
//
#ifndef FILTER_MASK_H
#define FILTER_MASK_H
#include "jpeg_io.h"
void sobel_filtering(image_s *im, image_s *new_im,
int sx, int ex, int sy, int ey);
#endif
//image median_filter(image in, int size)
#ifndef _MEDIANFILTER_H_
#define _MEDIANFILTER_H_
// Signal/image element type
typedef double element;
// 1D MEDIAN FILTER, window size 5
// signal - input signal
// result - output signal, NULL for inplace processing
// N - length of the signal
//void medianfilter(element* signal, element* result, int N);
25
// 2D MEDIAN FILTER, window size 3x3
// image - input image
// result - output image, NULL for inplace processing
// N - width of the image
// M - height of the image
void medianfilter(element* image, element* result, int N, int M);
#endif
// median_filter.c
//
// Revision History
// ----------------
//
// F. Gholami 2013-03-18 - Original
//
//
// Description:
// ------------------
// Image spatial filter
//
//http://www.librow.com/articles/article-1/appendix-a-2
// 2D MEDIAN FILTER implementation
// image - input image
// result - output image
// N - width of the image
// M - height of the image
void _medianfilter(const element* image, element* result, int N, int M)
{
// Move window through all elements of the image
for (int m = 1; m < M - 1; ++m)
for (int n = 1; n < N - 1; ++n)
{
// Pick up window elements
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 * N + i];
// Order elements (only half of them)
for (int j = 0; j < 5; ++j)
{
// Find position of minimum element
int min = j;
for (int l = j + 1; l < 9; ++l)
if (window[l] < window[min])
min = l;
// Put found minimum element in its place
const element temp = window[j];
window[j] = window[min];
window[min] = temp;
}
// Get result - the middle element
result[(m - 1) * (N - 2) + n - 1] = window[4];
}
}
26
// 2D MEDIAN FILTER wrapper
// image - input image
// result - output image
// N - width of the image
// M - height of the image
void medianfilter(element* image, element* result, int N, int M)
{
// Check arguments
if (!image || N < 1 || M < 1)
return;
// Allocate memory for signal extension
element* extension = new element[(N + 2) * (M + 2)];
// Check memory allocation
if (!extension)
return;
// Create image extension
for (int i = 0; i < M; ++i)
{
memcpy(extension + (N + 2) * (i + 1) + 1, image + N * i, N * sizeof(element));
extension[(N + 2) * (i + 1)] = image[N * i];
extension[(N + 2) * (i + 2) - 1] = image[N * (i + 1) - 1];
}
// Fill first line of image extension
memcpy(extension, extension + N + 2, (N + 2) * sizeof(element));
// Fill last line of image extension
memcpy(extension + (N + 2) * (M + 1), extension + (N + 2) * M, (N + 2) * sizeof(element));
// Call median filter implementation
_medianfilter(extension, result ? result : image, N + 2, M + 2);
// Free memory
delete[] extension;
}
27

More Related Content

What's hot

Ec section
Ec section Ec section
Ec section
Antriksh Saxena
 
Digital Image Fundamentals
Digital Image FundamentalsDigital Image Fundamentals
Digital Image Fundamentals
A B Shinde
 
Sign Language Recognition Using Image Processing For Mute People
Sign Language Recognition Using Image Processing For Mute PeopleSign Language Recognition Using Image Processing For Mute People
Sign Language Recognition Using Image Processing For Mute People
paperpublications3
 
Programming in matlab lesson5
Programming in matlab lesson5Programming in matlab lesson5
Programming in matlab lesson5
najmah17
 
Image Processing Using MATLAB
Image Processing Using MATLABImage Processing Using MATLAB
Image Processing Using MATLAB
Amarjeetsingh Thakur
 
3D reconstruction
3D reconstruction3D reconstruction
3D reconstruction
Jorge Leandro, Ph.D.
 
OpenCV presentation series- part 4
OpenCV presentation series- part 4OpenCV presentation series- part 4
OpenCV presentation series- part 4
Sairam Adithya
 
Ijetcas14 372
Ijetcas14 372Ijetcas14 372
Ijetcas14 372
Iasir Journals
 
FORGERY (COPY-MOVE) DETECTION IN DIGITAL IMAGES USING BLOCK METHOD
FORGERY (COPY-MOVE) DETECTION IN DIGITAL IMAGES USING BLOCK METHODFORGERY (COPY-MOVE) DETECTION IN DIGITAL IMAGES USING BLOCK METHOD
FORGERY (COPY-MOVE) DETECTION IN DIGITAL IMAGES USING BLOCK METHOD
editorijcres
 
Image Texture Analysis
Image Texture AnalysisImage Texture Analysis
Image Texture Analysis
lalitxp
 
Hybrid Technique for Copy-Move Forgery Detection Using L*A*B* Color Space
Hybrid Technique for Copy-Move Forgery Detection Using L*A*B* Color Space Hybrid Technique for Copy-Move Forgery Detection Using L*A*B* Color Space
Hybrid Technique for Copy-Move Forgery Detection Using L*A*B* Color Space
IJEEE
 
Digital Image Processing
Digital Image ProcessingDigital Image Processing
Digital Image Processing
Shaleen Saini
 
Image processing with matlab
Image processing with matlabImage processing with matlab
Image processing with matlab
neetirajsinh
 
Structure and Motion - 3D Reconstruction of Cameras and Structure
Structure and Motion - 3D Reconstruction of Cameras and StructureStructure and Motion - 3D Reconstruction of Cameras and Structure
Structure and Motion - 3D Reconstruction of Cameras and Structure
Giovanni Murru
 
3D Reconstruction from Multiple uncalibrated 2D Images of an Object
3D Reconstruction from Multiple uncalibrated 2D Images of an Object3D Reconstruction from Multiple uncalibrated 2D Images of an Object
3D Reconstruction from Multiple uncalibrated 2D Images of an Object
Ankur Tyagi
 
Image pre processing
Image pre processingImage pre processing
Image pre processing
Ashish Kumar
 
isvc_draft6_final_1_harvey_mudd (1)
isvc_draft6_final_1_harvey_mudd (1)isvc_draft6_final_1_harvey_mudd (1)
isvc_draft6_final_1_harvey_mudd (1)
David Tenorio
 
Oc2423022305
Oc2423022305Oc2423022305
Oc2423022305
IJERA Editor
 
A0280105
A0280105A0280105
A0280105
researchinventy
 
Image processing with matlab
Image processing with matlabImage processing with matlab
Image processing with matlab
Aman Gupta
 

What's hot (20)

Ec section
Ec section Ec section
Ec section
 
Digital Image Fundamentals
Digital Image FundamentalsDigital Image Fundamentals
Digital Image Fundamentals
 
Sign Language Recognition Using Image Processing For Mute People
Sign Language Recognition Using Image Processing For Mute PeopleSign Language Recognition Using Image Processing For Mute People
Sign Language Recognition Using Image Processing For Mute People
 
Programming in matlab lesson5
Programming in matlab lesson5Programming in matlab lesson5
Programming in matlab lesson5
 
Image Processing Using MATLAB
Image Processing Using MATLABImage Processing Using MATLAB
Image Processing Using MATLAB
 
3D reconstruction
3D reconstruction3D reconstruction
3D reconstruction
 
OpenCV presentation series- part 4
OpenCV presentation series- part 4OpenCV presentation series- part 4
OpenCV presentation series- part 4
 
Ijetcas14 372
Ijetcas14 372Ijetcas14 372
Ijetcas14 372
 
FORGERY (COPY-MOVE) DETECTION IN DIGITAL IMAGES USING BLOCK METHOD
FORGERY (COPY-MOVE) DETECTION IN DIGITAL IMAGES USING BLOCK METHODFORGERY (COPY-MOVE) DETECTION IN DIGITAL IMAGES USING BLOCK METHOD
FORGERY (COPY-MOVE) DETECTION IN DIGITAL IMAGES USING BLOCK METHOD
 
Image Texture Analysis
Image Texture AnalysisImage Texture Analysis
Image Texture Analysis
 
Hybrid Technique for Copy-Move Forgery Detection Using L*A*B* Color Space
Hybrid Technique for Copy-Move Forgery Detection Using L*A*B* Color Space Hybrid Technique for Copy-Move Forgery Detection Using L*A*B* Color Space
Hybrid Technique for Copy-Move Forgery Detection Using L*A*B* Color Space
 
Digital Image Processing
Digital Image ProcessingDigital Image Processing
Digital Image Processing
 
Image processing with matlab
Image processing with matlabImage processing with matlab
Image processing with matlab
 
Structure and Motion - 3D Reconstruction of Cameras and Structure
Structure and Motion - 3D Reconstruction of Cameras and StructureStructure and Motion - 3D Reconstruction of Cameras and Structure
Structure and Motion - 3D Reconstruction of Cameras and Structure
 
3D Reconstruction from Multiple uncalibrated 2D Images of an Object
3D Reconstruction from Multiple uncalibrated 2D Images of an Object3D Reconstruction from Multiple uncalibrated 2D Images of an Object
3D Reconstruction from Multiple uncalibrated 2D Images of an Object
 
Image pre processing
Image pre processingImage pre processing
Image pre processing
 
isvc_draft6_final_1_harvey_mudd (1)
isvc_draft6_final_1_harvey_mudd (1)isvc_draft6_final_1_harvey_mudd (1)
isvc_draft6_final_1_harvey_mudd (1)
 
Oc2423022305
Oc2423022305Oc2423022305
Oc2423022305
 
A0280105
A0280105A0280105
A0280105
 
Image processing with matlab
Image processing with matlabImage processing with matlab
Image processing with matlab
 

Viewers also liked

Social Media Reccomendations
Social Media ReccomendationsSocial Media Reccomendations
Social Media Reccomendations
Mattie Borman
 
AMIT KR BASU
AMIT KR BASUAMIT KR BASU
AMIT KR BASU
Amit Basu
 
62. şura suresi
62. şura suresi62. şura suresi
62. şura suresi
TEBYİN-ÜL-KUR’AN
 
Gerakan Orang Tua Asuh ( GOTA ) Generasi Berdaya Mandiri
Gerakan Orang Tua Asuh ( GOTA ) Generasi Berdaya Mandiri Gerakan Orang Tua Asuh ( GOTA ) Generasi Berdaya Mandiri
Gerakan Orang Tua Asuh ( GOTA ) Generasi Berdaya Mandiri
Yayasan Mandiri Amanah
 
75. secde suresi
75. secde suresi75. secde suresi
75. secde suresi
TEBYİN-ÜL-KUR’AN
 
Docker
DockerDocker
Getting started with AppArmor
Getting started with AppArmorGetting started with AppArmor
Getting started with AppArmor
Francesco Pira
 
Case Study - Implementing DevOps for a complex hardware/software-based networ...
Case Study - Implementing DevOps for a complex hardware/software-based networ...Case Study - Implementing DevOps for a complex hardware/software-based networ...
Case Study - Implementing DevOps for a complex hardware/software-based networ...
Sailaja Tennati
 
Writing HTTP Middleware In Go
Writing HTTP Middleware In GoWriting HTTP Middleware In Go
Writing HTTP Middleware In Go
Shiju Varghese
 
Three things that rowhammer taught me by Halvar Flake
Three things that rowhammer taught me by Halvar FlakeThree things that rowhammer taught me by Halvar Flake
Three things that rowhammer taught me by Halvar Flake
n|u - The Open Security Community
 
Effective Java - Chapter 3: Methods Common to All Objects
Effective Java - Chapter 3: Methods Common to All ObjectsEffective Java - Chapter 3: Methods Common to All Objects
Effective Java - Chapter 3: Methods Common to All Objects
İbrahim Kürce
 
Cátedra de Liderazgo Adaptativo, Prof. Héctor Lira (Versión 1)
Cátedra de Liderazgo Adaptativo, Prof. Héctor Lira (Versión 1)Cátedra de Liderazgo Adaptativo, Prof. Héctor Lira (Versión 1)
Cátedra de Liderazgo Adaptativo, Prof. Héctor Lira (Versión 1)
Héctor Lira
 

Viewers also liked (12)

Social Media Reccomendations
Social Media ReccomendationsSocial Media Reccomendations
Social Media Reccomendations
 
AMIT KR BASU
AMIT KR BASUAMIT KR BASU
AMIT KR BASU
 
62. şura suresi
62. şura suresi62. şura suresi
62. şura suresi
 
Gerakan Orang Tua Asuh ( GOTA ) Generasi Berdaya Mandiri
Gerakan Orang Tua Asuh ( GOTA ) Generasi Berdaya Mandiri Gerakan Orang Tua Asuh ( GOTA ) Generasi Berdaya Mandiri
Gerakan Orang Tua Asuh ( GOTA ) Generasi Berdaya Mandiri
 
75. secde suresi
75. secde suresi75. secde suresi
75. secde suresi
 
Docker
DockerDocker
Docker
 
Getting started with AppArmor
Getting started with AppArmorGetting started with AppArmor
Getting started with AppArmor
 
Case Study - Implementing DevOps for a complex hardware/software-based networ...
Case Study - Implementing DevOps for a complex hardware/software-based networ...Case Study - Implementing DevOps for a complex hardware/software-based networ...
Case Study - Implementing DevOps for a complex hardware/software-based networ...
 
Writing HTTP Middleware In Go
Writing HTTP Middleware In GoWriting HTTP Middleware In Go
Writing HTTP Middleware In Go
 
Three things that rowhammer taught me by Halvar Flake
Three things that rowhammer taught me by Halvar FlakeThree things that rowhammer taught me by Halvar Flake
Three things that rowhammer taught me by Halvar Flake
 
Effective Java - Chapter 3: Methods Common to All Objects
Effective Java - Chapter 3: Methods Common to All ObjectsEffective Java - Chapter 3: Methods Common to All Objects
Effective Java - Chapter 3: Methods Common to All Objects
 
Cátedra de Liderazgo Adaptativo, Prof. Héctor Lira (Versión 1)
Cátedra de Liderazgo Adaptativo, Prof. Héctor Lira (Versión 1)Cátedra de Liderazgo Adaptativo, Prof. Héctor Lira (Versión 1)
Cátedra de Liderazgo Adaptativo, Prof. Héctor Lira (Versión 1)
 

Similar to ee8220_project_W2013_v5

International Journal of Computational Engineering Research(IJCER)
 International Journal of Computational Engineering Research(IJCER)  International Journal of Computational Engineering Research(IJCER)
International Journal of Computational Engineering Research(IJCER)
ijceronline
 
Log polar coordinates
Log polar coordinatesLog polar coordinates
Log polar coordinates
Oğul Göçmen
 
Enhanced Optimization of Edge Detection for High Resolution Images Using Veri...
Enhanced Optimization of Edge Detection for High Resolution Images Using Veri...Enhanced Optimization of Edge Detection for High Resolution Images Using Veri...
Enhanced Optimization of Edge Detection for High Resolution Images Using Veri...
ijcisjournal
 
Digital Image Processing
Digital Image ProcessingDigital Image Processing
Digital Image Processing
Ankur Nanda
 
Jpeg
JpegJpeg
Use of Wavelet Transform Extension for Graphics Image Compression using JPEG2...
Use of Wavelet Transform Extension for Graphics Image Compression using JPEG2...Use of Wavelet Transform Extension for Graphics Image Compression using JPEG2...
Use of Wavelet Transform Extension for Graphics Image Compression using JPEG2...
CSCJournals
 
COMPARISON OF GPU AND FPGA HARDWARE ACCELERATION OF LANE DETECTION ALGORITHM
COMPARISON OF GPU AND FPGA HARDWARE ACCELERATION OF LANE DETECTION ALGORITHMCOMPARISON OF GPU AND FPGA HARDWARE ACCELERATION OF LANE DETECTION ALGORITHM
COMPARISON OF GPU AND FPGA HARDWARE ACCELERATION OF LANE DETECTION ALGORITHM
sipij
 
Comparison of GPU and FPGA Hardware Acceleration of Lane Detection Algorithm
Comparison of GPU and FPGA Hardware Acceleration of Lane Detection AlgorithmComparison of GPU and FPGA Hardware Acceleration of Lane Detection Algorithm
Comparison of GPU and FPGA Hardware Acceleration of Lane Detection Algorithm
sipij
 
IJ-M&M08.ppt
IJ-M&M08.pptIJ-M&M08.ppt
IJ-M&M08.ppt
SenukeTest
 
JPEG
JPEGJPEG
Ijarcet vol-2-issue-7-2319-2322
Ijarcet vol-2-issue-7-2319-2322Ijarcet vol-2-issue-7-2319-2322
Ijarcet vol-2-issue-7-2319-2322
Editor IJARCET
 
Ijarcet vol-2-issue-7-2319-2322
Ijarcet vol-2-issue-7-2319-2322Ijarcet vol-2-issue-7-2319-2322
Ijarcet vol-2-issue-7-2319-2322
Editor IJARCET
 
11.0003www.iiste.org call for paper_d_discrete cosine transform for image com...
11.0003www.iiste.org call for paper_d_discrete cosine transform for image com...11.0003www.iiste.org call for paper_d_discrete cosine transform for image com...
11.0003www.iiste.org call for paper_d_discrete cosine transform for image com...
Alexander Decker
 
A Biometric Approach to Encrypt a File with the Help of Session Key
A Biometric Approach to Encrypt a File with the Help of Session KeyA Biometric Approach to Encrypt a File with the Help of Session Key
A Biometric Approach to Encrypt a File with the Help of Session Key
Sougata Das
 
O0342085098
O0342085098O0342085098
O0342085098
ijceronline
 
A PROJECT REPORT ON REMOVAL OF UNNECESSARY OBJECTS FROM PHOTOS USING MASKING
A PROJECT REPORT ON REMOVAL OF UNNECESSARY OBJECTS FROM PHOTOS USING MASKINGA PROJECT REPORT ON REMOVAL OF UNNECESSARY OBJECTS FROM PHOTOS USING MASKING
A PROJECT REPORT ON REMOVAL OF UNNECESSARY OBJECTS FROM PHOTOS USING MASKING
IRJET Journal
 
B018110915
B018110915B018110915
B018110915
IOSR Journals
 
Hardware software co simulation of edge detection for image processing system...
Hardware software co simulation of edge detection for image processing system...Hardware software co simulation of edge detection for image processing system...
Hardware software co simulation of edge detection for image processing system...
eSAT Publishing House
 
Information search using text and image query
Information search using text and image queryInformation search using text and image query
Information search using text and image query
eSAT Journals
 
Efficient Image Compression Technique using JPEG2000 with Adaptive Threshold
Efficient Image Compression Technique using JPEG2000 with Adaptive ThresholdEfficient Image Compression Technique using JPEG2000 with Adaptive Threshold
Efficient Image Compression Technique using JPEG2000 with Adaptive Threshold
CSCJournals
 

Similar to ee8220_project_W2013_v5 (20)

International Journal of Computational Engineering Research(IJCER)
 International Journal of Computational Engineering Research(IJCER)  International Journal of Computational Engineering Research(IJCER)
International Journal of Computational Engineering Research(IJCER)
 
Log polar coordinates
Log polar coordinatesLog polar coordinates
Log polar coordinates
 
Enhanced Optimization of Edge Detection for High Resolution Images Using Veri...
Enhanced Optimization of Edge Detection for High Resolution Images Using Veri...Enhanced Optimization of Edge Detection for High Resolution Images Using Veri...
Enhanced Optimization of Edge Detection for High Resolution Images Using Veri...
 
Digital Image Processing
Digital Image ProcessingDigital Image Processing
Digital Image Processing
 
Jpeg
JpegJpeg
Jpeg
 
Use of Wavelet Transform Extension for Graphics Image Compression using JPEG2...
Use of Wavelet Transform Extension for Graphics Image Compression using JPEG2...Use of Wavelet Transform Extension for Graphics Image Compression using JPEG2...
Use of Wavelet Transform Extension for Graphics Image Compression using JPEG2...
 
COMPARISON OF GPU AND FPGA HARDWARE ACCELERATION OF LANE DETECTION ALGORITHM
COMPARISON OF GPU AND FPGA HARDWARE ACCELERATION OF LANE DETECTION ALGORITHMCOMPARISON OF GPU AND FPGA HARDWARE ACCELERATION OF LANE DETECTION ALGORITHM
COMPARISON OF GPU AND FPGA HARDWARE ACCELERATION OF LANE DETECTION ALGORITHM
 
Comparison of GPU and FPGA Hardware Acceleration of Lane Detection Algorithm
Comparison of GPU and FPGA Hardware Acceleration of Lane Detection AlgorithmComparison of GPU and FPGA Hardware Acceleration of Lane Detection Algorithm
Comparison of GPU and FPGA Hardware Acceleration of Lane Detection Algorithm
 
IJ-M&M08.ppt
IJ-M&M08.pptIJ-M&M08.ppt
IJ-M&M08.ppt
 
JPEG
JPEGJPEG
JPEG
 
Ijarcet vol-2-issue-7-2319-2322
Ijarcet vol-2-issue-7-2319-2322Ijarcet vol-2-issue-7-2319-2322
Ijarcet vol-2-issue-7-2319-2322
 
Ijarcet vol-2-issue-7-2319-2322
Ijarcet vol-2-issue-7-2319-2322Ijarcet vol-2-issue-7-2319-2322
Ijarcet vol-2-issue-7-2319-2322
 
11.0003www.iiste.org call for paper_d_discrete cosine transform for image com...
11.0003www.iiste.org call for paper_d_discrete cosine transform for image com...11.0003www.iiste.org call for paper_d_discrete cosine transform for image com...
11.0003www.iiste.org call for paper_d_discrete cosine transform for image com...
 
A Biometric Approach to Encrypt a File with the Help of Session Key
A Biometric Approach to Encrypt a File with the Help of Session KeyA Biometric Approach to Encrypt a File with the Help of Session Key
A Biometric Approach to Encrypt a File with the Help of Session Key
 
O0342085098
O0342085098O0342085098
O0342085098
 
A PROJECT REPORT ON REMOVAL OF UNNECESSARY OBJECTS FROM PHOTOS USING MASKING
A PROJECT REPORT ON REMOVAL OF UNNECESSARY OBJECTS FROM PHOTOS USING MASKINGA PROJECT REPORT ON REMOVAL OF UNNECESSARY OBJECTS FROM PHOTOS USING MASKING
A PROJECT REPORT ON REMOVAL OF UNNECESSARY OBJECTS FROM PHOTOS USING MASKING
 
B018110915
B018110915B018110915
B018110915
 
Hardware software co simulation of edge detection for image processing system...
Hardware software co simulation of edge detection for image processing system...Hardware software co simulation of edge detection for image processing system...
Hardware software co simulation of edge detection for image processing system...
 
Information search using text and image query
Information search using text and image queryInformation search using text and image query
Information search using text and image query
 
Efficient Image Compression Technique using JPEG2000 with Adaptive Threshold
Efficient Image Compression Technique using JPEG2000 with Adaptive ThresholdEfficient Image Compression Technique using JPEG2000 with Adaptive Threshold
Efficient Image Compression Technique using JPEG2000 with Adaptive Threshold
 

More from Farhad Gholami

slides_low_rank_matrix_optim_farhad
slides_low_rank_matrix_optim_farhadslides_low_rank_matrix_optim_farhad
slides_low_rank_matrix_optim_farhad
Farhad Gholami
 
Implementation of a Localization System for Sensor Networks-berkley
Implementation of a Localization System for Sensor Networks-berkleyImplementation of a Localization System for Sensor Networks-berkley
Implementation of a Localization System for Sensor Networks-berkley
Farhad Gholami
 
zeropadding
zeropaddingzeropadding
zeropadding
Farhad Gholami
 
FinalProject_Complete_6
FinalProject_Complete_6FinalProject_Complete_6
FinalProject_Complete_6
Farhad Gholami
 
EE8120_Projecte_15
EE8120_Projecte_15EE8120_Projecte_15
EE8120_Projecte_15
Farhad Gholami
 
Direct_studies_report13
Direct_studies_report13Direct_studies_report13
Direct_studies_report13
Farhad Gholami
 
Presentation_final_Farhad_9
Presentation_final_Farhad_9Presentation_final_Farhad_9
Presentation_final_Farhad_9
Farhad Gholami
 

More from Farhad Gholami (7)

slides_low_rank_matrix_optim_farhad
slides_low_rank_matrix_optim_farhadslides_low_rank_matrix_optim_farhad
slides_low_rank_matrix_optim_farhad
 
Implementation of a Localization System for Sensor Networks-berkley
Implementation of a Localization System for Sensor Networks-berkleyImplementation of a Localization System for Sensor Networks-berkley
Implementation of a Localization System for Sensor Networks-berkley
 
zeropadding
zeropaddingzeropadding
zeropadding
 
FinalProject_Complete_6
FinalProject_Complete_6FinalProject_Complete_6
FinalProject_Complete_6
 
EE8120_Projecte_15
EE8120_Projecte_15EE8120_Projecte_15
EE8120_Projecte_15
 
Direct_studies_report13
Direct_studies_report13Direct_studies_report13
Direct_studies_report13
 
Presentation_final_Farhad_9
Presentation_final_Farhad_9Presentation_final_Farhad_9
Presentation_final_Farhad_9
 

ee8220_project_W2013_v5

  • 1. Project Report Edge Detection and median filtering for colour JPEG images By: Farhad Gholami EE8220: Advanced Digital Filters April 2013 1
  • 2. Table of Contents Introduction :...........................................................................................................................................................................3 Gradient : ................................................................................................................................................................................3 Image gradient : ......................................................................................................................................................................3 Sobel Algorithm : ....................................................................................................................................................................4 JPEG Overview ........................................................................................................................................................................5 JPEG Images processing software : ........................................................................................................................................6 Median Filter ...........................................................................................................................................................................7 2D median filter: .....................................................................................................................................................................7 Sorting algorthm: ....................................................................................................................................................................7 Setting up Compile and Linker : ..............................................................................................................................................8 Appendix A: Install open source JPEG library for VisualStudio...............................................................................................10 JPEG Library construction steps:............................................................................................................................................10 Appendix B: Source code.......................................................................................................................................................11 2
  • 3. Introduction : JPEG is a widely used standard to compress digital images and bbject detection using edges is a common task in machine vision and there are algorithms to highlight the edges of the objects using a mathematical operator to achieve this task . In this project we will introduce a “Sobel edge detection” algorithm working on JPEG colour images and also introduce a median filter implementation to reject impulsive noise. We use a PC running Windows7 for our development .Source code is in C and IDE is MSVisualStudio10. Digital Image: A (digital) color image is includes color information for each pixel.For visually acceptable results, it is necessary to provide three values(color channels) for each pixel. The RGB color space is commonly used in computer displays.A color image has three values per pixel and they measure the intensity and chrominance of light. The actual information stored in the digital image data is the brightness information in each spectral band. Eight bits per sample (3x8=24 bits per pixel) is adequate for most applications. Gradient : The gradient of a scalar field points in the direction of the greatest rate of increase of the scalar field, and whose magnitude is that rate of increase. In simple terms, the variation in space of any quantity can be represented (e.g. graphically) by a slope. The gradient represents the steepness and direction of that slope. In below two images, the scalar field is in black and white, black representing higher values, and its corresponding gradient is represented by blue arrows. The gradient at a point is a vector pointing in the direction of the steepest slope at that point. The steepness of the slope at any point is given by the magnitude of the gradient vector Image gradient : Mathematically, the gradient of a two-variable function (here the image intensity function) at each image point is a 2D vector with the components given by the derivatives in the horizontal and vertical directions. At each image point, the gradient vector points in the direction of largest possible intensity increase, and the length of the gradient vector corresponds to the rate of change in that direction. Since the intensity function of a digital image is only known at discrete points, derivatives of this function cannot be defined unless we assume that there is an underlying continious intensity function which has been sampled at the image points. With some additional assumptions, the derivative of the continuous intensity function can be computed as a function on the 3
  • 4. sampled intensity function, i.e., the digital image. It turns out that the derivatives at any particular point are functions of the intensity values at virtually all image points. However, approximations of these derivative functions can be defined at lesser or larger degrees of accuracy. Sobel Algorithm : The Sobel operator represents a rather inaccurate approximation of the image gradient, but is still of sufficient quality to be of practical use in many applications. More precisely, it uses intensity values only in a 3×3 region around each image point to approximate the corresponding image gradient, and it uses only integer values for the coefficients which weight the image intensities to produce the gradient approximation. Mathematically, the sobel uses two 3×3 kernels which are convolved with the original image to calculate approximations of the derivatives - one for horizontal changes, and one for vertical as below shows: The operator uses two 3×3 kernels which are convolved with the original image to calculate approximations of the derivatives - one for horizontal changes, and one for vertical. If we define A as the source image, and Gx and Gy are two images which at each point contain the horizontal and vertical derivative approximations, the computations are as follows: 4
  • 5. Below is algorithm implemented in C: JPEG Overview JPEG (Joint Photographic Experts Group) [ISO] is a compression scheme to reduce the size of continuous-tone digital images. It is particularly useful to save space on storage devices, where compression ratio and image quality are more important than compression speed or delay. Many of those applications use JPEG or a related image compression method. JPEG lossy process is based on the Discrete Cosine Transform (DCT). It packs the transformed data in sequential order, using zero suppression in combination with Huffman symbol coding. We will focus on the IDCT related steps to show where our improvements apply. 5
  • 6. JPEG Images processing software : Pixels are points in a graphical image and colour channels being used to show relative intensity. For example Gray scale has 1 channel and RGB have 3 channels for each pixel. Size of an image contains three dimensions: width, height, channels(3 for RGB). To use JPEG image read and write functions in our c code , we use open source libjpeg library which implements decoding and encoding functions and utilities for handling JPEG images. This library is maintained by the Independent JPEG Group (IJG). For example this is how we read an image file: Appendix-A includes information for compile and setting up this library. 6
  • 7. Median Filter Neighbourhood averaging can suppress isolated out-of-range noise, but the side effect is that it also blurs sudden changes (corresponding to high spatial frequencies) such as sharp edges. The median filter is an effective method that can suppress isolated noise without blurring sharp edges. Specifically, the median filter replaces a pixel by the median of all pixels in the neighbourhood: 2D median filter: The window of a 2D median filter can be of any central symmetric shape. The pixel at the center will be replaced by the median of all pixel values inside the window. Sorting algorthm: Sorting is necessary for finding the median of a set of values. Various sorting algorithm with complexity of O(n log2 n)However in this case, assuming the number of pixels is quite limited, a simple sorting method with complexity )(n**2) can be used. The code segment below sorts an array of k elements: Below diagram illustrates how different tools take various input files and generate appropriate output files to ultimately be used in building an executable image. mpi.lib and jpeg.lib libraries will be added to final image using linker. 7
  • 8. Setting up Compile and Linker : Below pictures shows how to set up IDE and other details: 8
  • 9. I 9
  • 10. Appendix A: Install open source JPEG library for VisualStudio First we need to download jpeg free library from here : http://www.ijg.org/ Library makefile builds the IJG library as a static Win32 library, and optional application make files builds the sample applications as Win32 console applications. (building the applications lets us run the self-test.) Provided make files we used work as project files in Visual Studio 2010 or later. JPEG Library construction steps: 1. Open the command prompt, change to the main directory and execute the command line NMAKE /f makefile.vc setup-v10 This will move jconfig.vc to jconfig.h and makefiles to project files. (Note that the renaming is critical!) 2. Open the solution file jpeg.sln, build the library project. (If you are using Visual Studio more recent than 2010 (v10), you'll probably get a message saying that the project files are being updated.) 3. Open the solution file apps.sln, build the application projects. 4. To perform the self-test, execute the command line : NMAKE /f makefile.vc test-build 5. Move the application .exe files from `app`Release to an appropriate location on your path. Below pictures shows how to configure and install the IJG software for MS-VC++ 2010 Developer Studio : 10
  • 11. Note: You might need to installing Windows SDK if your host dose not have win32.mak file. Appendix B: Source code // jpeg_io.c // // Revision History // ---------------- // // F. Gholami 2013-04-12 - Original 11
  • 12. // // // Description: // ------------------ // JPEG related APIs // #include <stdio.h> #include <stdlib.h> #include <string.h> #include <setjmp.h> #include "jpeg_io.h" image_s *image_outline_new(int h, int w, int c); void image_write_JPEG_file (char *filename , image_s *image , int quality) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; FILE * outfile ; // target file JSAMPROW row_pointer[1]; // pointer to JSAMPLE row[s] int row_stride; // physical row width in image buffer printf("image_write_JPEG_file: starts n"); cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); // Step 2: specify destination file //printf("image_write_JPEG_file: step2 specify destination filen"); if ((outfile = fopen ( filename , "wb"))== NULL ) { fprintf(stderr , "JPEG_WRITE_ERROR : can't open %s/n", filename); exit(1); } jpeg_stdio_dest(&cinfo ,outfile); // Step 3: set parameters for compression //printf("image_write_JPEG_file: step3 set parameters for compressionn"); cinfo.image_width = image->width; // image width and height, in pixels cinfo.image_height = image->height; cinfo.input_components = image->components; // #components per pixel if((image->components) == 3) { cinfo.in_color_space = JCS_RGB; // colorspace of input image } else { cinfo.in_color_space = JCS_GRAYSCALE; // colorspace of input image } jpeg_set_defaults(&cinfo); jpeg_set_quality(&cinfo, quality, TRUE); // limit baseline-JPEG values // Step 4: Start compressor 12
  • 13. //printf("image_write_JPEG_file: step4 Start compressorn"); jpeg_start_compress(&cinfo, TRUE); // Step 5: while (scan lines remain to be written) //printf("image_write_JPEG_file: step5 while (scan lines remain to be written)n"); row_stride = image->width * image->components; while (cinfo.next_scanline < cinfo.image_height) { row_pointer[0] = image->buffer[cinfo.next_scanline]; (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); } // Step 6: Finish compression //printf("image_write_JPEG_file: step6 Finish compressionn"); jpeg_finish_compress (&cinfo); fclose (outfile); // Step 7: release JPEG compression object //printf("image_write_JPEG_file: step7 release JPEG compression object n"); printf("image_write_JPEG_file: release JPEG compression object n"); jpeg_destroy_compress(&cinfo); } //======================================================= // Error stuff - copy&paste void my_error_exit (j_common_ptr cinfo) { // cinfo->err really points to a my_error_mgr struct, so coerce pointer my_error_ptr myerr = (my_error_ptr) cinfo->err; // Always display the message. // We could postpone this until after returning, if we chose. (*cinfo->err->output_message) (cinfo); // Return control to the setjmp point longjmp(myerr->setjmp_buffer, 1); } //============================================================== image_s *image_read_JPEG_file(char *filename) { struct jpeg_decompress_struct cinfo; struct my_error_mgr jerr; // More stuff FILE *infile; //source file JSAMPARRAY buffer; // Output row buffer */ int row_stride; // physical row width in output buffer */ int current_row = 0; image_s *image; // printf("image_read_JPEG_file: step0 reading JPEG file n"); if ((infile=fopen(filename , "rb")) ==NULL) 13
  • 14. { fprintf (stderr , "image_read_JPEG_file: cant open %sn" , filename); return 0; } fprintf (stderr , "image_read_JPEG_file: opened %sn" , filename); // Step 1: allocate and initialize JPEG decompression object */ printf("image_read_JPEG_file: step1 allocate/init JPEG decompress objectn"); cinfo.err = jpeg_std_error (&jerr.pub); jerr.pub.error_exit = my_error_exit; if (setjmp(jerr.setjmp_buffer) ) { jpeg_destroy_decompress(&cinfo); fclose (infile); printf("image_read_JPEG_file: step1 ... exit!!!n"); return 0; } // Now we can initialize the JPEG decompression object. */ //printf("image_read_JPEG_file: decompress starts...n"); jpeg_create_decompress (&cinfo); //printf("image_read_JPEG_file: decompress ends...n"); // Step 2: specify data source file */ //printf("image_read_JPEG_file: step2 specify data source filen"); jpeg_stdio_src (&cinfo,infile); // Step 3: read file parameters with jpeg_read_header() //printf("image_read_JPEG_file: step3 read file parametersn"); (void)jpeg_read_header (&cinfo ,TRUE); // Step 5: Start decompressor //printf("image_read_JPEG_file: step4 Start decompressor n"); (void) jpeg_start_decompress(&cinfo); // Step 5 1/2 init image_s object //printf("image_read_JPEG_file: step5 init image_s objectn"); image = image_outline_new( cinfo.output_height, cinfo.output_width, cinfo.output_components); row_stride = cinfo.output_width * cinfo.output_components; buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); // Step 6: while (scan lines remain to be read) */ // jpeg_read_scanlines(...); //printf("image_read_JPEG_file: step6 scan lines remain to be readn"); while (cinfo.output_scanline < cinfo.output_height) { (void) jpeg_read_scanlines(&cinfo, buffer, 1); // Assume put_scanline_someplace wants a pointer and sample count. */ put_scanline_in_image_s(buffer[0], image, row_stride, current_row++); } // Step 7: Finish decompression */ 14
  • 15. //printf("image_read_JPEG_file: step7 finish decompression"); (void)jpeg_finish_decompress(&cinfo); // Step 8: Release JPEG decompression object */ // printf("image_read_JPEG_file: step8 release JPEG decompression objectn"); jpeg_destroy_decompress(&cinfo); fclose (infile); return image; } //======================================================================= image_s *image_outline_new(int h, int w, int c) { image_s *new; int i; //printf("image_outline_new:starts , create image h=%d, w=%d c=%d n", h,w,c); new = malloc(sizeof(image_s)); if(new == NULL) { fprintf(stderr, "image_outline_new: ERROR.. Out of memoryn"); exit(1); } new->buffer = malloc(sizeof(JSAMPLE *)*(h+2)); if(new->buffer == NULL) { fprintf(stderr, "image_outline_new: ERROR.. Out of memoryn"); exit(1); } new->buffer[0] = calloc(sizeof(JSAMPLE),(w+2)*c*(h+2)); if(new->buffer[0] == NULL) { fprintf(stderr, "image_outline_new: ERROR... Out of memoryn"); exit(1); } new->buffer[0] = new->buffer[0]+c; new->buffer = new->buffer + 1; for(i = 0; i <= h; i++) { new->buffer[i] = new->buffer[i-1]+(w+2)*c; } new->height = h; new->width = w; new->components = c; printf("image_outline_new: ends...n"); return new; } //=================================================================================== image_s *image_new(int h, int w, int c) { 15
  • 16. image_s *new; int i ; printf("image_new:starts , create image h=%d, w=%d c=%d n", h,w,c); new = malloc(sizeof(image_s)); new->buffer = malloc(sizeof(JSAMPLE *)*h); if(new->buffer == NULL) { fprintf(stderr, "image_new: Out of memory!n"); exit(1); } new->buffer[0] = malloc(sizeof(JSAMPLE)*w*c*h); if(new->buffer[0] == NULL) { fprintf(stderr,"image_new: Out of memory!n"); exit(1); } for(i=1; i<h; i++) { new->buffer[i] = new->buffer[i-1]+w*c; } new->height = h; new->width = w; new->components = c; printf("image_new: h=%d, w=%d c=%d n", h,w,c); printf("image_new: ends okn"); return new; } //===================================================================== void put_scanline_in_image_s(JSAMPROW buffer,image_s *image, int row_stride,int current_row) { memcpy(image->buffer[current_row],buffer, sizeof(JSAMPLE)*row_stride); } //===================================================================== // main.c // // Revision History // ---------------- // // F. Gholami 2012-03-29 - Original // // // Description: // ------------------ // Main file for parallel soble edge detection // #include <string.h> #include <stdlib.h> #include "mpi.h" #include "jpeg_io.h" 16
  • 17. #include "mpi_decomp.h" #include "sobel_filter.h" #define FILE_NAME_SIZE 2048 #define JPEG_QUALITY 20 #define DIMENSION_SIZE_2D 2 #define SPRINTF_BUFFER_SIZE 256 int main(int argc,char **argv) { image_s *im, *new_im ; int sx,sy,ex,ey; int sobel = TRUE; int currentarg = 1; char outfilename[FILE_NAME_SIZE]; int outn; // MPI variables int rank, rank2d; // Processor rank int numtasks; // No. of Processors MPI_Datatype MPI_Pixel; MPI_Datatype MPI_Image_block; MPI_Status status; int *displ; int i,j,k,ix; MPI_Comm comm2d; int nbr_left, nbr_right, nbr_up, nbr_down; int dims[DIMENSION_SIZE_2D], periods[DIMENSION_SIZE_2D], coords[DIMENSION_SIZE_2D], block[DIMENSION_SIZE_2D]; double startwtime = 0.0, endwtime; char processor_name[MPI_MAX_PROCESSOR_NAME]; int namelen; //MPI_Init MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &numtasks); MPI_Get_processor_name(processor_name,&namelen); fprintf(stdout,"Process %d of %d is on %sn", rank, numtasks, processor_name); fflush(stdout); if(rank == 0) //master node { startwtime = MPI_Wtime(); fprintf(stdout,"main: start time=%lf secn", startwtime ); } // default out filelename 17
  • 18. outn =sprintf_s (outfilename,256 , "%s" ,argv [argc-1]); sprintf_s(outfilename + outn,256,"_out.jpg"); printf("nmain: processor[%d] is aliven", rank); // Parse argv while(currentarg < argc-1) { if(0 == strcmp(argv[currentarg], "-o")) { currentarg++; sprintf_s(outfilename ,2048, "%s", argv[currentarg]); } currentarg++; } if(argc-currentarg ==1) { fprintf(stderr, "usage: %s [-1D][-sjpj-l n][-o outfile] filenamen", argv[0]); } // Read JPEG file(JPEG) printf("nRead JPEG file starts ....n"); im = image_read_JPEG_file ("C:/book/testimg.jpg"); if(rank == 0) { printf("main: Image loaded in memory=%lf secn", MPI_Wtime()); } printf("main: Proc[%d], image->w=%d image->h=%d image->c=%d n", rank, im->width, im->height, im->components); // MPI 2D Decomposition create dims[0] = 0; dims[1] = 0; periods[0] = FALSE; printf("main: MPI decomp2d creat ...n"); MPI_Dims_create(numtasks, DIMENSION_SIZE_2D, dims); printf("main: MPI_COMM_WORLD starts ...n"); MPI_Cart_create(MPI_COMM_WORLD, DIMENSION_SIZE_2D, dims, periods, TRUE, &comm2d); MPI_Comm_rank(comm2d, &rank2d); // MPI 2-d Decomposition init printf("main: Matrix 2D decomp init starts ...n"); matrix_2D_neighbors(comm2d, &nbr_up, &nbr_down, &nbr_left, &nbr_right); printf("main: Proc[%d], 2D-id=%d up=%d down=%d left=%d right=%dn", rank, rank2d, nbr_up, nbr_down, nbr_left, nbr_right); //matrix-decomposition printf("main: Matrix 2D decomp starts ...n"); matrix_2D_decomp( comm2d, im->width, im->height, im->components, &sx, &ex, &sy,&ey, block ); 18
  • 19. printf("main: Proc[%d], x:<%d,%d> y:<%d,%d> b:<%d,%d>n", rank2d, sx,ex, sy,ey, block[0],block[1]); printf("main:Proc[%d], edge detection starts n",rank2d); // edge detection if(rank2d == 0) { new_im = image_new (block[1]*dims[1], block[0]*dims[0], im->components); new_im->width = im->width; new_im->height = im->height; } else { new_im = image_new(block[1], block[0], im->components); } if(rank2d == 0) printf("main: Decomp fisnished at:%lf sn", MPI_Wtime()); for(ix=0;ix<1000;ix++) //to increase computional load sobel_filtering(im,new_im, sx,ex,sy,ey); printf("main:Sobel end n"); // Gather data printf("main: MPI Gather data...n"); MPI_Type_contiguous(im->components*sizeof(JSAMPLE), MPI_BYTE, &MPI_Pixel); MPI_Type_commit(&MPI_Pixel); if(rank2d == 0) //for master node { MPI_Type_vector (block[1] ,block[0], block[0]*dims[0] ,MPI_Pixel ,&MPI_Image_block); MPI_Type_commit (&MPI_Image_block); displ = safe_malloc (sizeof(int)*numtasks); for(i=0,k=0; i < dims[0];i++) { for(j=0; j<dims[1];j++,k++) { displ[k] = ( (j*block[1]*dims[0]) + i) * (block[0]*im->components) ; printf("main: Proc[%d], displ[%d] = %dn", rank2d ,k, displ[k]); } } } //rank2d==0 else//rank2d!=0 slave nodes { printf("main:Proc[%d],...mpi vectorn", rank2d); MPI_Type_vector(block[1],block[0],block[0],MPI_Pixel, &MPI_Image_block); MPI_Type_commit(&MPI_Image_block); } if(rank2d == 0) //in master mode { printf("main: MPI_Recv...n"); for(i = 1; i < numtasks; i++) { MPI_Recv(new_im->buffer[0]+displ[i], 1, MPI_Image_block, i,100,comm2d,&status); 19
  • 20. printf("main: Proc[0] recieved Image block from %d", i); } } else //in slav nodes { printf("main: MPI_Send...n"); MPI_Send(new_im->buffer[0],1,MPI_Image_block,0,100,comm2d); } printf("main: Proc[%d],Gather ... Donen", rank2d); // write output printf("main: write output..."); if(rank2d == 0) { image_write_JPEG_file(outfilename, new_im ,JPEG_QUALITY); endwtime = MPI_Wtime(); printf("wall clock time = %fn", endwtime-startwtime); } //MPI_Finish MPI_Type_free(&MPI_Image_block); MPI_Type_free(&MPI_Pixel); MPI_Comm_free(&comm2d); MPI_Finalize(); printf("n"); } // mpi_decomp.c // // Revision History // ---------------- // // F. Gholami 2013-04-12 - Original // // // Description: // ------------------ // Test of MPI/MPE decomp of matrix for parallel soble edge detection #include "mpi_decomp.h" //---------------------------------------------------------------------------- // matrix_2D_neighbors // This routine show the neighbors in a 2-d decomposition of // the domain. This assumes that MPI_Cart_create has already been called //-------------------------------------------------- void matrix_2D_neighbors(MPI_Comm comm, int *nbr_up, int *nbr_down, int *nbr_left, int *nbr_right) { printf("matrix_2D_neighbors: starts ...n"); MPI_Cart_shift(comm,0,1, nbr_left, nbr_right); MPI_Cart_shift(comm,1,1, nbr_up, nbr_down); } //----------------------------------------------------- 20
  • 21. // matrix_2D_decomp // This routine computes the decomposition //--------------------------------------------------------- void matrix_2D_decomp(MPI_Comm comm, int nodes_x, int nodes_y, int comp, int *start_x, int *end_x,int *start_y, int *end_y,int *block) { int dims[2]; int coords[2]; int periods[2]; printf("matrix_2D_decomp: starts ...n"); MPI_Cart_get( comm, 2, dims, periods, coords); block[0] = (nodes_x / dims[0]) +1; if(nodes_x % dims[0] == 0) { block[0]--; } block[1] = ( nodes_y / dims[1] + 1) ; if((nodes_y % dims[1]) == 0) { block[1]--; } *start_x = coords[0] * block[0]; *end_x = min( (coords[0]*block[0]+block[0]) , nodes_x) - 1; *start_y = coords[1]*block[1]; *end_y = min( coords[1]*block[1]+block[1]-1 , nodes_y-1) ; } // mylib.c // // Revision History // ---------------- // // F. Gholami 2012-11-22 - Original // // // Description: // ------------------ // Auxiliarry functions for parallel soble edge detection // #include "mylib.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #define OUT_OF_MEMORY "Out of memoryn" void *safe_malloc(size_t size) { void *new; new = malloc(size); 21
  • 22. if(new == NULL) { fprintf(stderr, OUT_OF_MEMORY); exit(1); } return new; } void *safe_calloc(size_t nelem, size_t elsize) { void *new; new = calloc(nelem,elsize); if(new == NULL) { fprintf(stderr, OUT_OF_MEMORY); exit(1); } return new; } void error_print_end(char *s) { fprintf(stderr, s); exit(1); } // sobel_filter.c // // Revision History // ---------------- // // F. Gholami 2013-04-18 - Original // // // Description: // ------------------ // Image spatial filter // #include "Sobel_filter.h" // Spatial filtering of image data */ // Sobel filter (horizontal differentiation // Input: image1[y][x] ---- Outout: image2[y][x] // Definition of Sobel filter in horizontal direction */ // int weight[3][3] = {{ -1, 0, 1 }, // { -2, 0, 2 }, // { -1, 0, 1 }}; 22
  • 23. //sobel operator void sobel_filtering(image_s *im, image_s *new_im, int sx, int ex, int sy,int ey) { int i,j,k; int x,y,sum; JSAMPLE **buf; buf = im->buffer; k = im->components; for(i = sy; i<ey+1; i++) for(j = sx*k;j < (ex+1)*k; j++) { x = buf[i+1][j-k]+2*buf[i+1][j]+buf[i+1][j+k]- (buf[i-1][j-k]+2*buf[i-1][j]+buf[i-1][j+k]); y = buf[i-1][j+k]+2*buf[i][j+k]+buf[i+1][j+k]- (buf[i-1][j-k]+2*buf[i][j-k]+buf[i+1][j-k]); sum = abs(x/4) + abs(y/4); if(sum > 255) //255 = 0xff sum = 255; new_im->buffer[i-sy][j-(sx*k)] = sum; } } // jpeg_io.h // // Revision History // ---------------- // // F. Gholami 2013-04-12 - Original // // // Description: // ------------------ // JPEG related APIs header // #ifndef JPEG_IO_H #define JPEG_IO_H #include <stdio.h> #include <setjmp.h> #include "jpeglib.h" #define TRUE 1 #define FALSE 0 typedef struct jpeg_compress_struct jpeg_com_struct; typedef struct jpeg_decompress_struct jpeg_decom_struct; struct image_s { JSAMPLE **buffer; int height; int width; int components; }; 23
  • 24. typedef struct image_s image_s; //-> struct my_error_mgr { struct jpeg_error_mgr pub; // "public" elds jmp_buf setjmp_buffer; // for return to caller }; typedef struct my_error_mgr * my_error_ptr; void image_write_JPEG_file (char *filename,image_s *iamge,int quality); image_s *image_read_JPEG_file (char * filename); image_s *image_new (int h, int w, int c); void put_scanline_in_image_s (JSAMPROW buffer, image_s *image, int row_stride,int current_row); #endif // mpi_decomp.h // // Revision History // ---------------- // // F. Gholami 2013-04-16 - Original // // // Description: // ------------------ // Header file for image filter // #ifndef MATRIX_DECOMP_H #define MATRIX_DECOMP_H #include <stdio.h> #include <stdlib.h> #include "mpi.h" #include "mylib.h" #define TRUE 1 #define FALSE 0 // matrix_2D_neighbors: This routine show the neighbors in a 2D decomposition of // the domain. This assumes that MPI_Cart_create has already been called void matrix_2D_neighbors(MPI_Comm comm, int *nbr_up, int *nbr_down, int *nbr_left, int *nbr_right); // matrix_2D_decomp : This routine computes the decomposition void matrix_2D_decomp(MPI_Comm comm, int nodes_x, int nodes_y, int comp, int *start_x, int *end_x, int *start_y, int *end_y, int *block); #endif // mylib.h // 24
  • 25. // Revision History // ---------------- // // F. Gholami 2013-04-16 - Original // // // Description: // ------------------ // Auxiliarry functions for parallel soble edge detection // #ifndef MYLIB_H #define MYLIB_H #include <stdlib.h> #include <stdio.h> void *safe_malloc(size_t size); void *safe_calloc(size_t nelem, size_t elsize); #endif // sobel_filter.h // // Revision History // ---------------- // // F. Gholami 2013-04-18 - Original // // // Description: // ------------------ // Image filter header file for parallel soble edge detection // #ifndef FILTER_MASK_H #define FILTER_MASK_H #include "jpeg_io.h" void sobel_filtering(image_s *im, image_s *new_im, int sx, int ex, int sy, int ey); #endif //image median_filter(image in, int size) #ifndef _MEDIANFILTER_H_ #define _MEDIANFILTER_H_ // Signal/image element type typedef double element; // 1D MEDIAN FILTER, window size 5 // signal - input signal // result - output signal, NULL for inplace processing // N - length of the signal //void medianfilter(element* signal, element* result, int N); 25
  • 26. // 2D MEDIAN FILTER, window size 3x3 // image - input image // result - output image, NULL for inplace processing // N - width of the image // M - height of the image void medianfilter(element* image, element* result, int N, int M); #endif // median_filter.c // // Revision History // ---------------- // // F. Gholami 2013-03-18 - Original // // // Description: // ------------------ // Image spatial filter // //http://www.librow.com/articles/article-1/appendix-a-2 // 2D MEDIAN FILTER implementation // image - input image // result - output image // N - width of the image // M - height of the image void _medianfilter(const element* image, element* result, int N, int M) { // Move window through all elements of the image for (int m = 1; m < M - 1; ++m) for (int n = 1; n < N - 1; ++n) { // Pick up window elements 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 * N + i]; // Order elements (only half of them) for (int j = 0; j < 5; ++j) { // Find position of minimum element int min = j; for (int l = j + 1; l < 9; ++l) if (window[l] < window[min]) min = l; // Put found minimum element in its place const element temp = window[j]; window[j] = window[min]; window[min] = temp; } // Get result - the middle element result[(m - 1) * (N - 2) + n - 1] = window[4]; } } 26
  • 27. // 2D MEDIAN FILTER wrapper // image - input image // result - output image // N - width of the image // M - height of the image void medianfilter(element* image, element* result, int N, int M) { // Check arguments if (!image || N < 1 || M < 1) return; // Allocate memory for signal extension element* extension = new element[(N + 2) * (M + 2)]; // Check memory allocation if (!extension) return; // Create image extension for (int i = 0; i < M; ++i) { memcpy(extension + (N + 2) * (i + 1) + 1, image + N * i, N * sizeof(element)); extension[(N + 2) * (i + 1)] = image[N * i]; extension[(N + 2) * (i + 2) - 1] = image[N * (i + 1) - 1]; } // Fill first line of image extension memcpy(extension, extension + N + 2, (N + 2) * sizeof(element)); // Fill last line of image extension memcpy(extension + (N + 2) * (M + 1), extension + (N + 2) * M, (N + 2) * sizeof(element)); // Call median filter implementation _medianfilter(extension, result ? result : image, N + 2, M + 2); // Free memory delete[] extension; } 27