Hough transform: Difference between revisions

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

edits