This Image Processing Reference section displays the code for an example program that demonstrates how to calculate a Fourier transform for the color channels of an image.
<?php function Clamp($iGray) { if ($iGray < 0) { return 0; } elseif ($iGray > 255) { return 255; } else { return $iGray; } } // The sign indicates whether it is a forward (1) or inverse (-1) transform function FFT($daData, $iLength, $iSign) { $daSines = new SplFixedArray($iLength+1); $daCosines = new SplFixedArray($iLength+1); $iBits = IntVal(round(Log($iLength)/Log(2))); for ($i = 0; $i < $iLength + 1; ++$i) { $daSines[$i] = $iSign*sin((3.141592654*$i)/$iLength); $daCosines[$i] = cos((3.141592654*$i)/$iLength); } $iU = 0; for ($i = 0; $i < $iLength; ++$i) { $iIndex = 0; for ($j = 0; $j < $iBits; ++$j) { $iU = (1<<$j); $iIndex = (($iIndex<<1) + (($iU&$i)>>$j)); } $iIndex <<= 1; $iIndex2 = ($i<<1); if ($iIndex2 < $iIndex) { $dTemp = $daData[$iIndex2]; $daData[$iIndex2] = $daData[$iIndex]; $daData[$iIndex] = $dTemp; $dTemp = $daData[$iIndex2 + 1]; $daData[$iIndex2 + 1] = $daData[$iIndex + 1]; $daData[$iIndex + 1] = $dTemp; } } $iArraySize = ($iLength << 1); for ($iIncr = 2; $iIncr < $iArraySize; $iIncr <<=1) { $iStep = ($iIncr << 1); for ($iU = 0; $iU < $iIncr; $iU += 2) { $a = ($iU << $iBits); $iIndex = IntVal(($a - ($a % $iIncr)) / $iIncr); $dCos = $daCosines[$iIndex]; $dSin = $daSines[$iIndex]; for ($i = $iU; $i < $iArraySize; $i += $iStep) { $j = $i + $iIncr; $dTR = $dCos*$daData[$j]-$dSin*$daData[$j+1]; $dTI = $dCos*$daData[$j+1]+$dSin*$daData[$j]; $daData[$j]=$daData[$i]-$dTR; $daData[$i]=$daData[$i]+$dTR; $daData[$j+1]=$daData[$i+1]-$dTI; $daData[$i+1]=$daData[$i+1]+$dTI; } } } } function CreateFourierTransformColorChannelsImage($qColorImage) { $iW = ImageSX($qColorImage); $iH = ImageSY($qColorImage); // Allocate the color channel transform images $qImageR = ImageCreate(256, 256); $qImageG = ImageCreate(256, 256); $qImageB = ImageCreate(256, 256); for ($iC = 0; $iC < 256; ++$iC) { ImageColorAllocate($qImageR, $iC, 0, 0); ImageColorAllocate($qImageG, 0, $iC, 0); ImageColorAllocate($qImageB, 0, 0, $iC); } // Create the Red, Green, and Blue Channel images for ($j = 0; $j < $iH; ++$j) { for ($i = 0; $i < $iW; ++$i) { $qColor = ImageColorAt($qColorImage, $i, $j); $iRed = (($qColor >> 16) & 0xFF); $iGreen = (($qColor >> 8) & 0xFF); $iBlue = ($qColor & 0xFF); ImageSetPixel($qImageR, $i, $j, $iRed); ImageSetPixel($qImageG, $i, $j, $iGreen); ImageSetPixel($qImageB, $i, $j, $iBlue); } } $qaChannelImages = array(); $qaChannelImages[0] = $qImageR; $qaChannelImages[1] = $qImageG; $qaChannelImages[2] = $qImageB; $daCmplIm = new SplFixedArray(2*$iW*$iH); $daComplex = new SplFixedArray(2*$iW); for ($iImage = 0; $iImage < 3; ++$iImage) { $qCurrImage = $qaChannelImages[$iImage]; for($i = 0; $i < $iW; ++$i) { for($j = 0; $j < $iW; ++$j) { $daCmplIm[2*$i + 2*$iW*$j] = ImageColorAt($qCurrImage, $i, $j); $daCmplIm[2*$i + 1 + 2*$iW*$j] = 0; } } // Transform the rows for($iY = 0; $iY < $iW; ++$iY) { $iR = $iY*($iW << 1); $iDW = ($iW << 1); for($iX = 0; $iX < $iDW; ++$iX) { $daComplex[$iX] = $daCmplIm[$iR + $iX]; } FFT($daComplex, $iW, 1); for($iX = 0; $iX < $iDW; ++$iX) { $daCmplIm[$iR + $iX] = $daComplex[$iX]; } } for($iX = 0; $iX < $iDW; $iX +=2) { for($iY = 0; $iY < $iW; ++$iY) { $iR = $iY*($iW << 1); $daComplex[2*$iY] = $daCmplIm[$iR + $iX]; $daComplex[2*$iY + 1] = $daCmplIm[$iR + $iX + 1]; } FFT($daComplex, $iW, 1); $dScale = $iW*$iW; for($iY = 0; $iY < $iW; ++$iY) { $iR = $iY*($iW << 1); $daCmplIm[$iR + $iX] = ($daComplex[2*$iY]/$iW); $daCmplIm[$iR + $iX + 1] = ($daComplex[2*$iY + 1]/$iW); } } // Copy the image data back after the transform for($i = 0; $i < $iW; ++$i) { for($j = 0; $j < $iW; ++$j) { $iCurrPixel = Clamp(IntVal(round(sqrt( $daCmplIm[2*$i + 2*$iW*$j]*$daCmplIm[2*$i + 2*$iW*$j] + $daCmplIm[2*$i + 2*$iW*$j + 1]*$daCmplIm[2*$i + 2*$iW*$j + 1])))); $iHalfWidth = $iW/2; $iX = 0; $iY = 0; if ($i < $iHalfWidth) { $iX = $iHalfWidth - $i - 1; } else { $iX = $iHalfWidth + $iW - $i - 1; } if ($j < $iHalfWidth) { $iY = $iHalfWidth - $j - 1; } else { $iY = $iHalfWidth + $iW - $j - 1; } ImageSetPixel($qCurrImage, $iX, $iY, $iCurrPixel); } } } $qFourierChannelImage = ImageCreateTrueColor(2*$iW, 2*$iH); // Copy the transformed color channel images ImageCopyMerge($qFourierChannelImage, $qColorImage, 0, 0, 0, 0, $iW, $iH, 100); ImageCopyMerge($qFourierChannelImage, $qImageR, $iW, 0, 0, 0, $iW, $iH, 100); ImageCopyMerge($qFourierChannelImage, $qImageG, $iW, $iH, 0, 0, $iW, $iH, 100); ImageCopyMerge($qFourierChannelImage, $qImageB, 0, $iH, 0, 0, $iW, $iH, 100); ImageDestroy($qImageR); ImageDestroy($qImageG); ImageDestroy($qImageB); return $qFourierChannelImage; } $qOriginalImage = ImageCreateFromPng("Moses256x256.png"); $qFourierChannelImage = CreateFourierTransformColorChannelsImage($qOriginalImage); Header('Content-type: image/png'); ImagePng($qFourierChannelImage); ImageDestroy($qOriginalImage); ImageDestroy($qFourierChannelImage); ?>
© 20072024 XoaX.net LLC. All rights reserved.