• Programming
• Internet

# 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);

ImagePng(\$qEdgesImage);
ImageDestroy(\$qOriginalImage);
ImageDestroy(\$qEdgesImage);
?>```