Hough transform: Difference between revisions
Content added Content deleted
m (→{{header|J}}: Update for J8) |
(→{{header|Haskell}}: Adjusted some names to avoid a wiki formatting glitch (+ hlint, hindent)) |
||
Line 198: | Line 198: | ||
-- Library JuicyPixels: |
-- Library JuicyPixels: |
||
import Codec.Picture |
import Codec.Picture |
||
(DynamicImage(ImageRGB8, ImageRGBA8), Image, PixelRGB8(PixelRGB8), |
|||
PixelRGBA8(PixelRGBA8), imageWidth, imageHeight, pixelAt, |
|||
generateImage, readImage, pixelMap, savePngImage) |
|||
import Codec.Picture.Types (extractLumaPlane, dropTransparency) |
import Codec.Picture.Types (extractLumaPlane, dropTransparency) |
||
dot |
|||
⚫ | |||
:: Num a |
|||
⚫ | |||
dot (x1, y1) (x2, y2) = x1 * x2 + y1 * y2 |
dot (x1, y1) (x2, y2) = x1 * x2 + y1 * y2 |
||
mag |
|||
⚫ | |||
:: Floating a |
|||
⚫ | |||
mag a = sqrt $ dot a a |
mag a = sqrt $ dot a a |
||
sub |
|||
⚫ | |||
:: Num a |
|||
⚫ | |||
sub (x1, y1) (x2, y2) = (x1 - x2, y1 - y2) |
sub (x1, y1) (x2, y2) = (x1 - x2, y1 - y2) |
||
fromIntegralP |
fromIntegralP |
||
:: (Integral a, Num b) |
|||
=> (a, a) -> (b, b) |
|||
fromIntegralP (x, y) = (fromIntegral x, fromIntegral y) |
fromIntegralP (x, y) = (fromIntegral x, fromIntegral y) |
||
Line 232: | Line 240: | ||
xCenter = wMax `div` 2 |
xCenter = wMax `div` 2 |
||
yCenter = hMax `div` 2 |
yCenter = hMax `div` 2 |
||
⚫ | |||
lumaMap = extractLumaPlane image |
lumaMap = extractLumaPlane image |
||
⚫ | |||
gradient x y = |
gradient x y = |
||
let orig = pixelAt lumaMap x y |
let orig = pixelAt lumaMap x y |
||
x_ = pixelAt lumaMap (min (x + 1) wMax) y |
|||
y_ = pixelAt lumaMap x (min (y + 1) hMax) |
|||
in fromIntegralP (orig - |
in fromIntegralP (orig - x_, orig - y_) |
||
gradMap = |
|||
⚫ | |||
[ ((x, y), gradient x y) |
|||
| x <- [0 .. wMax] |
|||
, y <- [0 .. hMax] ] |
|||
-- The longest distance from the center, half the hypotenuse of the image. |
-- The longest distance from the center, half the hypotenuse of the image. |
||
distMax :: Double |
distMax :: Double |
||
distMax = (sqrt . fromIntegral $ height ^ 2 + width ^ 2) / 2 |
distMax = (sqrt . fromIntegral $ height ^ 2 + width ^ 2) / 2 |
||
{- |
{- |
||
The accumulation bins of the polar values. |
The accumulation bins of the polar values. |
||
Line 253: | Line 259: | ||
lines that go through that point in Hough space. |
lines that go through that point in Hough space. |
||
-} |
-} |
||
accBin = |
accBin = |
||
runSTArray $ |
|||
arr <- newArray ((0, 0), (thetaSize, distSize)) 0 |
|||
do arr <- newArray ((0, 0), (thetaSize, distSize)) 0 |
|||
forM_ gradMap $ |
|||
⚫ | |||
\((x, y), grad) -> do |
|||
⚫ | |||
when (mag grad > 127) $ |
|||
when (mag grad > 127) $ |
|||
forM_ [0 .. thetaSize] $ |
|||
\theta -> do |
|||
let theta_ = |
|||
fromIntegral theta * 360 / fromIntegral thetaSize / 180 * |
|||
pi :: Double |
|||
dist = cos theta_ * x_ + sin theta_ * y_ |
|||
dist_ = truncate $ dist * fromIntegral distSize / distMax |
|||
idx = (theta, dist_) |
|||
when (dist_ >= 0 && dist_ < distSize) $ |
|||
⚫ | |||
⚫ | |||
return arr |
|||
return arr |
|||
maxAcc = F.maximum accBin |
maxAcc = F.maximum accBin |
||
-- The image representation of the accumulation bins. |
-- The image representation of the accumulation bins. |
||
hTransform x y = |
hTransform x y = |
||
let l = 255 - |
let l = 255 - truncate ((accBin ! (x, y)) / maxAcc * 255) |
||
in PixelRGB8 l l l |
in PixelRGB8 l l l |
||
⚫ | |||
hImage = generateImage hTransform thetaSize distSize |
hImage = generateImage hTransform thetaSize distSize |
||
Line 285: | Line 289: | ||
image <- readImage path |
image <- readImage path |
||
case image of |
case image of |
||
Left err |
Left err -> putStrLn err |
||
Right (ImageRGB8 |
Right (ImageRGB8 image_) -> doImage image_ |
||
Right (ImageRGBA8 |
Right (ImageRGBA8 image_) -> doImage $ pixelMap dropTransparency image_ |
||
_ |
_ -> putStrLn "Expecting RGB8 or RGBA8 image" |
||
where |
where |
||
doImage image = do |
doImage image = do |
||
Line 301: | Line 305: | ||
[path, outpath, thetaSize, distSize] -> |
[path, outpath, thetaSize, distSize] -> |
||
houghIO path outpath (read thetaSize) (read distSize) |
houghIO path outpath (read thetaSize) (read distSize) |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
'''Example use:''' |
'''Example use:''' |
||
<lang>HoughTransform Pentagon.png hough.png 360 360</lang> |
<lang>HoughTransform Pentagon.png hough.png 360 360</lang> |