Image Processing Computer Science

Kirsh-Robinson Compass Derivatives

This Image Processing Reference page displays the code for an example program that demonstrates how to create Kirsh-Robinson compass derivative filters to detect edges in images.

KirshRobinsonCompass.php

<?php
  function Clamp($iGray) {
    if ($iGray < 0) {
      return 0;
    } elseif ($iGray > 255) {
      return 255;
    } else {
      return $iGray;
    }
  }

  function CreateKirshRobinsonDerivativesImage($qOriginalImage) {
    $iWidth        = ImageSX($qOriginalImage);
    $iHeight       = ImageSY($qOriginalImage);
    $qGrayImage    = ImageCreate($iWidth, $iHeight);
    for ($iC = 0; $iC < 256; ++$iC) {
      ImageColorAllocate($qGrayImage, $iC, $iC, $iC);
    }
    // Convert the image to a grayscale
    for ($j = 0; $j < $iHeight; ++$j) {
      for ($i = 0; $i < $iWidth; ++$i) {
        $qColor  = ImageColorAt($qOriginalImage, $i, $j);
        $iRed    = (($qColor >> 16) & 0xFF);
        $iGreen  = (($qColor >> 8) & 0xFF);
        $iBlue   = ($qColor & 0xFF);
        // The gray level is a simple conversion for an uncorrected image
        $iGray   = IntVal(round(0.333*$iRed + 0.333*$iGreen + 0.333*$iBlue));
        ImageSetPixel($qGrayImage, $i, $j, $iGray);
      }
    }
    // Allocate the edge images and their colors
    $iaaaFilters = array();
    $aqEdgeImages = array();
    for ($iDir = 0; $iDir < 8; ++$iDir) {
      if ($iDir == 0) {
        // Use the divisor to set the contrast
        $iDiv = 30;
        // The prewitt operator for the "north" derivative
        $iaaaFilters[0] = array(
          array(5/$iDiv, 5/$iDiv, 5/$iDiv),
          array(-3/$iDiv, 0, -3/$iDiv),
          array(-3/$iDiv, -3/$iDiv, -3/$iDiv));
      } else {
        // Rotate the filter clockwise from the prior filter
        $iaaaFilters[$iDir] = array(array(0, 0, 0), array(0, 0, 0), array(0, 0, 0));
        $iaaaFilters[$iDir][0][0] = $iaaaFilters[$iDir - 1][1][0];
        $iaaaFilters[$iDir][0][1] = $iaaaFilters[$iDir - 1][0][0];
        $iaaaFilters[$iDir][0][2] = $iaaaFilters[$iDir - 1][0][1];
        $iaaaFilters[$iDir][1][0] = $iaaaFilters[$iDir - 1][2][0];
        $iaaaFilters[$iDir][1][2] = $iaaaFilters[$iDir - 1][0][2];
        $iaaaFilters[$iDir][2][0] = $iaaaFilters[$iDir - 1][2][1];
        $iaaaFilters[$iDir][2][1] = $iaaaFilters[$iDir - 1][2][2];
        $iaaaFilters[$iDir][2][2] = $iaaaFilters[$iDir - 1][1][2];
      }
      $aqEdgeImages[$iDir] = ImageCreate($iWidth, $iHeight);
      for ($iC = 0; $iC < 256; ++$iC) {
        ImageColorAllocate($aqEdgeImages[$iDir], $iC, $iC, $iC);
      }
    }
    $iaA = array(0, 0, 0, 0, 0, 0, 0, 0);
    for ($j = 1; $j < $iHeight - 1; ++$j) {
      for ($i = 1; $i < $iWidth - 1; ++$i) {
        for ($iA = 0; $iA < 8; ++$iA) {
          // Reset the accumulators to half for each pixel
          $iaA[$iA] = 128;
          for ($iFx = 0; $iFx < 3; ++$iFx) {
            for ($iFy = 0; $iFy < 3; ++$iFy) {
              $iGray  = ImageColorAt($qGrayImage, $i + $iFx - 1, $j + $iFy - 1);
              $iaA[$iA] += (($iaaaFilters[$iA][$iFy][$iFx])*$iGray);
            }
          }
          $iaA[$iA] = Clamp($iaA[$iA]);
          ImageSetPixel($aqEdgeImages[$iA], $i, $j, $iaA[$iA]);
        }
      }
    }
    $qMain = ImageCreateTrueColor(3*$iWidth, 3*$iHeight);
    // Copy the histogram images to the main image
    ImageCopyMerge($qMain, $qOriginalImage, $iWidth, $iHeight, 0, 0, $iWidth, $iHeight, 100);
    ImageCopyMerge($qMain, $aqEdgeImages[0], $iWidth, 0, 0, 0, $iWidth, $iHeight, 100);
    ImageCopyMerge($qMain, $aqEdgeImages[1], 2*$iWidth, 0, 0, 0, $iWidth, $iHeight, 100);
    ImageCopyMerge($qMain, $aqEdgeImages[2], 2*$iWidth, $iHeight, 0, 0, $iWidth, $iHeight, 100);
    ImageCopyMerge($qMain, $aqEdgeImages[3], 2*$iWidth, 2*$iHeight, 0, 0, $iWidth, $iHeight, 100);
    ImageCopyMerge($qMain, $aqEdgeImages[4], $iWidth, 2*$iHeight, 0, 0, $iWidth, $iHeight, 100);
    ImageCopyMerge($qMain, $aqEdgeImages[5], 0, 2*$iHeight, 0, 0, $iWidth, $iHeight, 100);
    ImageCopyMerge($qMain, $aqEdgeImages[6], 0, $iHeight, 0, 0, $iWidth, $iHeight, 100);
    ImageCopyMerge($qMain, $aqEdgeImages[7], 0, 0, 0, 0, $iWidth, $iHeight, 100);
    for ($i = 0; $i < 8; ++$i) {
      ImageDestroy($aqEdgeImages[$i]);
    }
    ImageDestroy($qGrayImage);
    return $qMain;
  }

  $qOriginalImage = ImageCreateFromPng("SermonOnTheMount_CarlHeinrichBloch.png");

  $qEdgesImage = CreateKirshRobinsonDerivativesImage($qOriginalImage);

  Header('Content-type: image/png');
  ImagePng($qEdgesImage);
  ImageDestroy($qOriginalImage);
  ImageDestroy($qEdgesImage);
?>
 
 

Output

 
 

© 2007–2022 XoaX.net LLC. All rights reserved.