🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: comp.sys.mac.programmer.codewarrior
5 messages
5 total messages Started by wall Fri, 10 Oct 2003 07:11
Red Eye Removing, How?
#668
Author: wall
Date: Fri, 10 Oct 2003 07:11
43 lines
2729 bytes
I use this code selected the rect which has red eyes.

// the selected rect which has red eye
// the selected image part GWorld - theSelectImageGWorld
LGWorld*	theSelectImageGWorld = NEW LGWorld( theSelectRect,32 );
ThrowIfNil_( theSelectImageGWorld ); 

// the orignal image GWorld - theImageGWorld
PixMapHandle	theOPixMapH = ::GetGWorldPixMap(
theImageGWorld->GetMacGWorld() );
PixMapHandle	theSelectPixMapH = ::GetGWorldPixMap(
theSelectImageGWorld->GetMacGWorld() );
Ptr theOBaseAddr = ::GetPixBaseAddr( theOPixMapH );
Ptr theSelectBaseAddr = ::GetPixBaseAddr( theSelectPixMapH );
short  theORowBytes = ::GetPixRowBytes( theOPixMapH );
short  theSelectRowBytes = ::GetPixRowBytes( theSelectPixMapH );

::LockPixels( theOPixMapH );
::LockPixels( theSelectPixMapH );
{
	Ptr		theSrcPtr, theDstPtr;
	for(short theY = mSelRectToImageOrignal.top; theY <
mSelRectToImageOrignal.bottom; theY++)
	{
		theSrcPtr = theOBaseAddr + theORowBytes * theY;
		theSrcPtr += mSelRectToImageOrignal.left << 2;
		theDstPtr = theSelectBaseAddr + theSelectRowBytes * ( theY -
mSelRectToImageOrignal.top );
		for (short theX = mSelRectToImageOrignal.left; theX <
mSelRectToImageOrignal.right; theX++)
		{
			* ((long*) theDstPtr++) = * ((long*) theSrcPtr++);
			* ((long*) theDstPtr++) = * ((long*) theSrcPtr++);
			* ((long*) theDstPtr++) = * ((long*) theSrcPtr++);
			* ((long*) theDstPtr++) = * ((long*) theSrcPtr++);

		}	
	}		
}
::UnlockPixels( theOPixMapH );
::UnlockPixels( theSelectPixMapH );

what can I do to removing red eye in the selected image part?
Re: Red Eye Removing, How?
#669
Author: Chris
Date: Fri, 10 Oct 2003 14:55
59 lines
3625 bytes
In article <7328a61a.0310092311.7ba03fa1@posting.google.com>,
 heroin_c@hotmail.com (wall) wrote:

> I use this code selected the rect which has red eyes.
> 
> // the selected rect which has red eye
> // the selected image part GWorld - theSelectImageGWorld
> LGWorld*	theSelectImageGWorld = NEW LGWorld( theSelectRect,32 );
> ThrowIfNil_( theSelectImageGWorld ); 
> 
> // the orignal image GWorld - theImageGWorld
> PixMapHandle	theOPixMapH = ::GetGWorldPixMap(
> theImageGWorld->GetMacGWorld() );
> PixMapHandle	theSelectPixMapH = ::GetGWorldPixMap(
> theSelectImageGWorld->GetMacGWorld() );
> Ptr theOBaseAddr = ::GetPixBaseAddr( theOPixMapH );
> Ptr theSelectBaseAddr = ::GetPixBaseAddr( theSelectPixMapH );
> short  theORowBytes = ::GetPixRowBytes( theOPixMapH );
> short  theSelectRowBytes = ::GetPixRowBytes( theSelectPixMapH );
> 
> ::LockPixels( theOPixMapH );
> ::LockPixels( theSelectPixMapH );
> {
> 	Ptr		theSrcPtr, theDstPtr;
> 	for(short theY = mSelRectToImageOrignal.top; theY <
> mSelRectToImageOrignal.bottom; theY++)
> 	{
> 		theSrcPtr = theOBaseAddr + theORowBytes * theY;
> 		theSrcPtr += mSelRectToImageOrignal.left << 2;
> 		theDstPtr = theSelectBaseAddr + theSelectRowBytes * ( theY -
> mSelRectToImageOrignal.top );
> 		for (short theX = mSelRectToImageOrignal.left; theX <
> mSelRectToImageOrignal.right; theX++)
> 		{
> 			* ((long*) theDstPtr++) = * ((long*) theSrcPtr++);
> 			* ((long*) theDstPtr++) = * ((long*) theSrcPtr++);
> 			* ((long*) theDstPtr++) = * ((long*) theSrcPtr++);
> 			* ((long*) theDstPtr++) = * ((long*) theSrcPtr++);
> 
> 		}	
> 	}		
> }
> ::UnlockPixels( theOPixMapH );
> ::UnlockPixels( theSelectPixMapH );
> 
> what can I do to removing red eye in the selected image part?

As long as you can be relatively sure that the user has selected a close 
boundary around the pupil, you could just reduce the red level 
everywhere to the average of the green and blue values. This will help 
establish a reasonable intensity for the red channel and will capture 
any residual hilights that might be present. You may still need to bring 
down the overall intensity of each channel by some fixed percentage to 
avoid overly bright pupils.

Each 32-bit pixel is layed out as argb, 8 bits each. You should leave 
the a value alone.

Chris.
Re: Red Eye Removing, How?
#670
Author: Chris
Date: Fri, 10 Oct 2003 15:00
54 lines
3402 bytes
In article <7328a61a.0310092311.7ba03fa1@posting.google.com>,
 heroin_c@hotmail.com (wall) wrote:

> I use this code selected the rect which has red eyes.
> 
> // the selected rect which has red eye
> // the selected image part GWorld - theSelectImageGWorld
> LGWorld*	theSelectImageGWorld = NEW LGWorld( theSelectRect,32 );
> ThrowIfNil_( theSelectImageGWorld ); 
> 
> // the orignal image GWorld - theImageGWorld
> PixMapHandle	theOPixMapH = ::GetGWorldPixMap(
> theImageGWorld->GetMacGWorld() );
> PixMapHandle	theSelectPixMapH = ::GetGWorldPixMap(
> theSelectImageGWorld->GetMacGWorld() );
> Ptr theOBaseAddr = ::GetPixBaseAddr( theOPixMapH );
> Ptr theSelectBaseAddr = ::GetPixBaseAddr( theSelectPixMapH );
> short  theORowBytes = ::GetPixRowBytes( theOPixMapH );
> short  theSelectRowBytes = ::GetPixRowBytes( theSelectPixMapH );
> 
> ::LockPixels( theOPixMapH );
> ::LockPixels( theSelectPixMapH );
> {
> 	Ptr		theSrcPtr, theDstPtr;
> 	for(short theY = mSelRectToImageOrignal.top; theY <
> mSelRectToImageOrignal.bottom; theY++)
> 	{
> 		theSrcPtr = theOBaseAddr + theORowBytes * theY;
> 		theSrcPtr += mSelRectToImageOrignal.left << 2;
> 		theDstPtr = theSelectBaseAddr + theSelectRowBytes * ( theY -
> mSelRectToImageOrignal.top );
> 		for (short theX = mSelRectToImageOrignal.left; theX <
> mSelRectToImageOrignal.right; theX++)
> 		{
> 			* ((long*) theDstPtr++) = * ((long*) theSrcPtr++);
> 			* ((long*) theDstPtr++) = * ((long*) theSrcPtr++);
> 			* ((long*) theDstPtr++) = * ((long*) theSrcPtr++);
> 			* ((long*) theDstPtr++) = * ((long*) theSrcPtr++);
> 
> 		}	
> 	}		
> }
> ::UnlockPixels( theOPixMapH );
> ::UnlockPixels( theSelectPixMapH );
> 
> what can I do to removing red eye in the selected image part?

I should add that you may want to leave a pixel alone if its red value 
does not exceed some high threshold. This will prevent discolration of 
the iris's inside the boundary. You could precalculate the threshold by 
histogramming the contents and looking for a sharp increase in the value 
of the red channel. Or you could use a fixed value.

Chris.
Re: Red Eye Removing, How?
#671
Author: wall
Date: Sat, 11 Oct 2003 01:35
3 lines
1380 bytes
Thanks Chris.
But could you give me some code about this.My english is very poor,so
I think maybe I can understand your idea from source code.
Re: Red Eye Removing, How?
#654
Author: Chris
Date: Tue, 21 Oct 2003 20:11
39 lines
2534 bytes
In article <7328a61a.0310101735.6ad75c32@posting.google.com>,
 heroin_c@hotmail.com (wall) wrote:

> Thanks Chris.
> But could you give me some code about this.My english is very poor,so
> I think maybe I can understand your idea from source code.

HI,
actually I don't have any code. that was just a general process I was 
describing. It might go something like this:

/* pass 1 -histogram red values */

UInt8 totals[256];
for( each pixel )
   r = (r value)
   totals[r]++

/* analyse histogram -find maximum drop off. this is very crude! */
/* you should definitely find a better way to find the level at */
/* which red eye is occurring. */
UInt32 threshold = 254;
Uint32 delta = 0;
for( i = 0; i < 254; i++ )
   if( delta < totals[i + 1] - totals[i] ) {
      delta = totals[i + 1] - totals[i];
      threshold = i;
      }

/* threshold contains the level at which redeye is deemed to be present*/

/* pass 2 -modify red values */
for( each pixel )
   r = (r value)
   if( r >= threshold )
      (r value) = (b value + g value) / 2

/* pass 2 discards red values over the threshold and replaces them
with the average of b and g */
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads