scalacv
Members list
Type members
Classlikes
How adaptive thresholding weights each pixel's neighbourhood. A true enumeration.
How adaptive thresholding weights each pixel's neighbourhood. A true enumeration.
Attributes
- Source
- Enums.scala
- Supertypes
-
trait Enumtrait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
Border extrapolation.
Border extrapolation.
Plain rather than an enum-with-modifiers: BORDER_ISOLATED is a modifier, but it only means anything for ROI-based calls that scalacv does not expose yet, so it is deliberately omitted rather than offered and ignored.
==One type, two domains==
OpenCV packs two different sets of accepted values into this one int, and this enum is the union of them. copyMakeBorder (behind pad and border) and warpAffine (behind rotated) honour all five modes. The imgproc filter family — gaussianBlur, boxBlur, sobel, laplacian — does not: it rejects BorderType.Wrap, see that case and BorderType.requireFilterSupport.
Splitting the type (a FilterBorder without Wrap, widening into a TransformBorder with it) is the end state that would make the mistake unrepresentable, but it is a breaking change to four public signatures. Until then BorderType.requireFilterSupport is the check every filter operation must run on its border parameter, so the rejection lands at the Scala boundary instead of as an assertion failure inside OpenCV. BORDER_TRANSPARENT stays out of the enum entirely for a related reason: copyMakeBorder throws on it, and warpAffine with it leaves the freshly-allocated destination uninitialised, so the value can only ever produce a crash or garbage pixels.
Attributes
- Companion
- object
- Source
- Enums.scala
- Supertypes
-
trait Enumtrait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
Attributes
- Companion
- enum
- Source
- Enums.scala
- Supertypes
-
trait Sumtrait Mirrorclass Objecttrait Matchableclass Any
- Self type
-
BorderType.type
A liveness-checked, read-only view over a video frame that belongs to someone else.
A liveness-checked, read-only view over a video frame that belongs to someone else.
Video.frames and scalacv.zio's frameStream decode every frame into one reused native buffer — that is what keeps a two-hour video flat in memory. Before this type existed, the iterator handed out that buffer as a raw Mat, and nothing stopped a caller from smuggling the reference out of the loop: the next read overwrote its pixels underneath the retained reference, and once the scope released the buffer the retained reference pointed at freed native memory. Reading it was not an exception, it was a SIGSEGV — the exact crash Managed exists to prevent everywhere else in the library.
BorrowedMat detects sequential use after the frame source advances or closes. Every forwarded access — including the mat escape hatch — checks a liveness flag first and rejects an already-spent view with IllegalStateException before crossing JNI. The raw Mat returned by mat is checked only at extraction; it must not be retained or released.
This is a single-consumer borrow, not a concurrent lifetime lock. The check and native access are not atomic with advancing or closing the source: do not use a view concurrently with either operation. Clone while the source is paused if another thread/fiber needs the pixels. Serialized consumers may hop threads, but a volatile flag alone cannot make overlapping access safe.
Only the read-only surface a frame consumer needs is forwarded — geometry, pixel reads, dataAddr for identity checks, and clone for "I need to keep this one". Mutation is not forwarded on purpose: the buffer is owned by the frame source and is about to be decoded over, so a put through the view would be a write into someone else's next frame.
==What "live" means==
A view is live from the moment the frame source produces it until the source is next asked for a frame (next/hasNext on Video.frames' iterator, the next pull on a zio stream) or the source closes — whichever comes first. Asking is advancing: with decode-ahead iterators hasNext already overwrites the buffer, so the previous view is spent by the call, not by the one after.
Not a value type: two views over the same buffer compare by reference identity, and dataAddr — not equals — is the way to ask "same underlying buffer?".
Attributes
- Source
- BorrowedMat.scala
- Supertypes
-
class Objecttrait Matchableclass Any
Reports how this artifact was built. Present from the first commit so the build has a real compilation unit and so a consumer can report an accurate version in a bug report.
Reports how this artifact was built. Present from the first commit so the build has a real compilation unit and so a consumer can report an accurate version in a bug report.
Every value here is generated from build.mill's Deps block rather than typed out a second time — see core.generatedSources. That is not tidiness: a version written down in two places is a version that eventually disagrees with itself, and the failure is silent. A dependency bump used to move the build and leave this object (and the "add these lines" help text in OpenCv and scalacv.vision.Cascades) quoting the previous release, which is precisely the number a bug report or a broken classpath depends on being right.
Attributes
- Source
- Build.scala
- Supertypes
-
class Objecttrait Matchableclass Any
- Self type
-
Build.type
Attributes
- Companion
- class
- Source
- Camera.scala
- Supertypes
-
class Objecttrait Matchableclass Any
- Self type
-
Camera.type
High-level video capture — a camera or a video file, walked as owned Images.
High-level video capture — a camera or a video file, walked as owned Images.
Camera is the high-level counterpart to Video. Where Video.frames hands you one reused, borrowed Mat for zero-copy speed, Camera hands you a fresh owned Image per frame — one you can transform, detect on, annotate, or keep, on the same terms as any other Image. The price is one frame copy per iteration; when that matters, drop to Video.frames on the borrowed capture.
import scalacv.*
OpenCv.load()
// Process every frame of a file into an edge video. Reading `.mp4` is fine — the container restriction
// is the writer's: the default codec is MJPG, which opens only in an `.avi` (see [[Codec.Mjpg]]).
Camera.usingFile("clip.mp4") { cam =>
cam.recordTo("edges.avi")(_.gray.canny(80, 160).convert(ColorConversion.GrayToBgr))
}
// Grab a single webcam snapshot:
Camera.using(0)(_.snapshot().flatMap(_.write("shot.png")))
The capture is caller-owned: close it, or acquire it through Camera.using / Camera.usingFile, which close for you. Camera is AutoCloseable.
Attributes
- Companion
- object
- Source
- Camera.scala
- Supertypes
-
trait AutoCloseableclass Objecttrait Matchableclass Any
Which videoio backend to ask for.
Which videoio backend to ask for.
Any is the right answer almost always: OpenCV tries its registered backends in priority order and uses the first that can read the source. Naming one is for when that choice is wrong — forcing CaptureBackend.FFmpeg on a file that the image-sequence reader would otherwise claim, or forcing CaptureBackend.V4L2 on Linux so that a camera's native pixel format is honoured.
A backend that is not compiled into the OpenCV build on the classpath simply cannot open anything, so naming one turns a working open into a failing one. The bytedeco 4.13.0 builds do not all carry the same set — this is a portability decision, not a tuning knob.
Attributes
- Source
- Video.scala
- Supertypes
-
trait Enumtrait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
What the backend claims about an open capture.
What the backend claims about an open capture.
Every field is a CAP_PROP_* query, and every one of them is advisory. A live camera usually reports frameCount == 0 (or -1) because the question is meaningless; some containers report a frameCount that is off by a frame or two from what actually decodes; fps can be 0 for a camera that has not delivered a frame yet. Use these to size a org.opencv.videoio.VideoWriter or to show progress — never as a loop bound. The frame count that is true is the one frames hands you.
Attributes
- Source
- Video.scala
- Supertypes
-
trait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
How a capture should be opened.
How a capture should be opened.
==Timeouts are best-effort, and off by default==
VideoCapture.read has no timeout overload and blocks in native code, so a stream that stops delivering hangs the calling thread with nothing scalacv can do about it from the JVM side. OpenCV's only lever is CAP_PROP_OPEN_TIMEOUT_MSEC / CAP_PROP_READ_TIMEOUT_MSEC, which is:
- Backend-dependent. FFMPEG and GStreamer honour them for network sources. V4L2, AVFoundation and the built-in MJPEG reader ignore them entirely. Nothing in the API reports which you got.
- Only settable at open time.
VideoCapture.seton a not-yet-opened capture returnsfalse(measured), so the values have to travel through theopen(source, backend, params)overload. - Rejected outright by backends that do not understand them. Measured on this build: opening a local
.aviwith the timeout parameters attached yieldsisOpened == false, where the same file opens fine without them. Video therefore retries without the parameters rather than reporting a failure that is really "your backend has no timeout support".
They default to None because of the third point: paying a failed open, plus OpenCV's stderr noise, on every local file to configure something local files never need is the wrong default. Set them for network sources — RTSP, HTTP — where a hang is the failure mode you actually face.
==Why a camera needs warming up and a file does not==
A webcam is not ready the instant open returns. Auto-exposure, auto-white-balance and auto-gain are closed loops running on the device, and they need a handful of real frames to converge — which is why a naive open-then-snapshot so often yields a black or badly-under-exposed image and reports it as a success. There is no property to poll for "converged", so the only fix is to pull some frames and throw them away.
warmupFrames is how many to discard before the capture is handed back. It defaults to None, which means "let the source decide": Video.open(index, …) discards 5 and Video.open(source, …) discards 0. That split is the point — a file or an RTSP URL has no exposure loop, its first frame is exactly as correct as its hundredth, and discarding frames there would silently skip real content. Set it explicitly to override either default (Some(0) disables warm-up on a camera).
Value parameters
- backend
-
which videoio backend to ask for; see CaptureBackend.
- openTimeout
-
best-effort cap on how long opening the source may block.
- readTimeout
-
best-effort cap on how long a single frame read may block.
- warmupFrames
-
how many frames to grab and discard immediately after opening;
Nonetakes the per-source default described above.
Attributes
- Companion
- object
- Source
- Video.scala
- Supertypes
-
trait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
Attributes
- Companion
- class
- Source
- Video.scala
- Supertypes
-
trait Producttrait Mirrorclass Objecttrait Matchableclass Any
- Self type
-
CaptureOptions.type
A video container/codec, as a FOURCC — pure bit packing, no native call, so a codec can be named before OpenCv.load().
A video container/codec, as a FOURCC — pure bit packing, no native call, so a codec can be named before OpenCv.load().
Attributes
- Companion
- object
- Source
- Codec.scala
- Supertypes
-
trait Enumtrait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
Attributes
- Companion
- enum
- Source
- Codec.scala
- Supertypes
-
trait Sumtrait Mirrorclass Objecttrait Matchableclass Any
- Self type
-
Codec.type
Colour space conversions. A true enumeration.
Colour space conversions. A true enumeration.
Attributes
- Source
- Enums.scala
- Supertypes
-
trait Enumtrait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
A false-colour map — turns a single-channel image (a depth map, a motion field, any data) into a colour heatmap. The perceptually-uniform ones (Colormap.Viridis, Colormap.Magma, Colormap.Inferno, Colormap.Plasma, Colormap.Turbo) are the honest choice for data; Colormap.Jet is the classic-but-misleading rainbow.
A false-colour map — turns a single-channel image (a depth map, a motion field, any data) into a colour heatmap. The perceptually-uniform ones (Colormap.Viridis, Colormap.Magma, Colormap.Inferno, Colormap.Plasma, Colormap.Turbo) are the honest choice for data; Colormap.Jet is the classic-but-misleading rainbow.
Attributes
- Source
- Enums.scala
- Supertypes
-
trait Enumtrait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
One connected outline, copied out of native memory.
One connected outline, copied out of native memory.
OpenCV hands contours back as a java.util.List[MatOfPoint] — a list of live native handles the caller is expected to free individually. That is the single most reliable leak in the OpenCV Java API: nothing in the signature says the list owns anything, and the objects survive every reasonable-looking use of the result. So findContours copies the points across the boundary and frees the natives before it returns, and this type is ordinary immutable Scala data with no pointer behind it. It stays valid after the source Mat is released.
The measurements (Point carries Double) come back whole: findContours produces CV_32SC2, so every coordinate is an integer that happens to be widened.
Construction copies the points into an immutable Vector (see the companion's apply): the metrics are lazy, so a Contour that merely retained the caller's Seq would see a mutable buffer's later edits halfway through a measurement chain, and convexHull indexes into the points once per hull vertex — constant-time against a Vector, quadratic against a List.
Attributes
- Companion
- object
- Source
- Contours.scala
- Supertypes
-
trait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
Attributes
- Companion
- class
- Source
- Contours.scala
- Supertypes
-
trait Producttrait Mirrorclass Objecttrait Matchableclass Any
- Self type
-
Contour.type
How findContours compresses each contour. A true enumeration.
How findContours compresses each contour. A true enumeration.
Attributes
- Source
- Enums.scala
- Supertypes
-
trait Enumtrait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
Which contours findContours reports. A true enumeration.
Which contours findContours reports. A true enumeration.
Attributes
- Source
- Enums.scala
- Supertypes
-
trait Enumtrait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
The error policy.
The error policy.
The core cannot be "total". org.opencv.core.CvException escapes from ordinary in-memory operations, including on the empty Mat that a failed imread hands back, and no wrapper can prevent that. So scalacv draws the line deliberately:
Either[CvError, A]where failure is data-dependent and expected — a file that is not there, bytes that do not decode, a model that will not load.- Thrown IllegalArgumentException for precondition violations, which are programmer errors and should not be pattern-matched.
- Propagated CvError.NativeCall for everything OpenCV throws at us that we did not anticipate. Wrapped so the operation is named, never swallowed.
Attributes
Attributes
- Companion
- class
- Source
- CvError.scala
- Supertypes
-
trait Sumtrait Mirrorclass Objecttrait Matchableclass Any
- Self type
-
CvError.type
Everything scalacv can fail with.
Everything scalacv can fail with.
Modelled as an exception hierarchy rather than a pure ADT because it has to interoperate with a JNI boundary that throws: org.opencv.core.CvException escapes from ordinary Imgproc calls, and no wrapper can make the core total. The API returns Either[CvError, A] where failure is data-dependent and expected — a missing file, an undecodable image — and throws for programmer errors.
Attributes
- Companion
- object
- Source
- CvError.scala
- Supertypes
-
class RuntimeExceptionclass Exceptionclass Throwabletrait Serializableclass Objecttrait Matchableclass AnyShow all
- Known subtypes
-
class CalibrationFailedclass DecodeFailedclass EncodeFailedclass EndOfStreamclass LoadFailedclass NativeCallclass NativesMissingShow all
Text measurement — the one part of drawing that answers a question instead of changing an image.
Text measurement — the one part of drawing that answers a question instead of changing an image.
Attributes
- Source
- Draw.scala
- Supertypes
-
class Objecttrait Matchableclass Any
- Self type
-
Draw.type
A named, composable photo filter — an Image => Image transform you can name, chain, and apply.
A named, composable photo filter — an Image => Image transform you can name, chain, and apply.
The catalog in the companion is a set of ready-made "looks" built from the Image tone, colour, and stylisation operations; each is a Filter you apply with image.filter(Filter.vintage) or compose with andThen. Because a filter is just a named transform, your own are first-class: Filter("mine")(_.gamma(1.2).saturate(1.3)).
Like every Image transform, applying a filter consumes the image and returns a new one.
Attributes
- Companion
- object
- Source
- Filter.scala
- Supertypes
-
class Objecttrait Matchableclass Any
Attributes
- Companion
- class
- Source
- Filter.scala
- Supertypes
-
class Objecttrait Matchableclass Any
- Self type
-
Filter.type
How to mirror an image. Named by the visible effect, not OpenCV's axis-centric flip code.
How to mirror an image. Named by the visible effect, not OpenCV's axis-centric flip code.
Attributes
- Source
- Enums.scala
- Supertypes
-
trait Enumtrait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
Hershey fonts for putText. A true enumeration.
Hershey fonts for putText. A true enumeration.
Attributes
- Source
- Enums.scala
- Supertypes
-
trait Enumtrait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
The high-level, fluent face of scalacv — an owned image you transform by chaining.
The high-level, fluent face of scalacv — an owned image you transform by chaining.
Image is the layer to reach for first. It wraps a single native Mat and lets you express the common OpenCV shape — read, transform, detect, annotate, write — as one readable chain:
import scalacv.*
OpenCv.load()
for _ <- Image.read("photo.jpg").flatMap(_.gray.blur(2).canny(80, 160).write("edges.png"))
yield ()
==Move semantics: a transform consumes the image==
Every transform (gray, blur, canny, resize, crop, a draw*) returns a new Image and spends the one it was called on — using the old handle afterwards throws IllegalStateException rather than reading freed memory. That is what makes the chain leak-free without a scope: each step frees (or hands on) the previous Mat, so a long pipeline holds exactly one live Mat at a time, never a pile of intermediates. It is Mats.chain's guarantee, surfaced as a type.
The trade is that you cannot use one Image twice. To branch, take a copy first, or drop to the mid-level API on a borrowed mat.
==Queries borrow, terminals consume==
A query (width, faces, qrCodes, contours) only reads, so it leaves the image alive. A terminal (write, bytes, close) consumes it and releases the Mat. If a value escapes the chain without ever reaching a terminal it leaks, exactly as a stray Managed would — so prefer Image.reading, which owns live successors and copy branches until its callback returns. managed preserves that scope; only an explicit detach transfers a branch out of it.
==Not a wall==
Image never hides the library underneath it. mat borrows the raw org.opencv.core.Mat for any org.opencv.* call this type does not wrap; managed hands the whole Managed over. The high-level API is the pleasant default, not a ceiling. Domain verbs that only happen to start from an image — face and marker detection, pose and track overlays, OCR preparation, background replacement — are extension methods brought in with import scalacv.vision.*, not members of this class, which is why they are absent below; they read image.faces(detector) all the same.
==Failures==
A transform does not return an Either: when OpenCV itself rejects the pixels (a data-dependent failure this library cannot foresee), the op throws CvError.NativeCall, naming the operation — an unchecked throw, so it is invisible at the call site. Argument mistakes this library can see are rejected up front with IllegalArgumentException. Only the Either-returning boundary methods (Image.read, write, bytes, Image.decode) turn failure into a value. To fold a transform's throw into an Either too, wrap it with Cv.attempt. Reusing an already-consumed image throws IllegalStateException; see Managed for -Dscalacv.trackOwnership=true, which points the error at the consuming call.
Image is AutoCloseable, so scala.util.Using manages it too.
Attributes
- Companion
- object
- Source
- Image.scala
- Supertypes
-
trait AutoCloseableclass Objecttrait Matchableclass Any
Attributes
- Companion
- class
- Source
- Image.scala
- Supertypes
-
class Objecttrait Matchableclass Any
- Self type
-
Image.type
Reading, writing, encoding and decoding images — the boundary between OpenCV and everything else.
Reading, writing, encoding and decoding images — the boundary between OpenCV and everything else.
This is the one place in the library where OpenCV's error reporting is genuinely inconsistent, and the whole point of the object is to flatten that into a single Either. Two distinct failure shapes come out of org.opencv.imgcodecs.Imgcodecs:
imdecodenever throws for bytes that are not an image. It returns aMatwithempty() == true(and logs afindDecoderwarning to stderr). Anyone who forgets theempty()check gets aCvExceptionseveral call frames later, from anImgprocoperation that had nothing to do with the mistake.imencodethrowsCvExceptionwhen the extension names no known encoder — sohaveImageWriteris consulted first and that case is returned as CvError.EncodeFailed before the throw can happen, rather than being recovered from OpenCV's error text.
Every function here returns Either[CvError, ?] covering both. The encode failures share the one CvError.EncodeFailed type, so case EncodeFailed(...) catches them all.
==The file I/O is done by the JVM, not by OpenCV== read and write do not call imread/imwrite. They open the file with java.nio.file and leave OpenCV only the codec work, through decode and encode. The reason is the path. The JNI layer narrows a Java String with GetStringUTFChars, so the native side receives modified UTF-8 bytes, and OpenCV's imgcodecs hands those bytes straight to fopen. On Windows the C runtime interprets them in the process's ANSI code page, so any non-ASCII character in the path resolves to a different, nonexistent name: imread then returns an empty Mat and imwrite returns false — indistinguishable from "the file is not there" and "the directory is not writable". Upstream has not fixed this (opencv#4292 is still open in 4.13) and exposes no wide-character entry point to call instead. Reading and writing the bytes on the JVM side avoids the narrowing altogether, and as a side effect lets both functions report which of the causes they used to lump together actually happened.
The price is that the encoded file passes through a JVM byte array: peak heap grows by its size, and a file above 2 GB is out of reach, because Files.readAllBytes cannot return an array that long. Routing around that with a memory-mapped buffer was rejected — imdecode needs a MatOfByte built from a JVM array anyway, so the copy is not avoidable here.
The same narrowing hazard applies to every other String-path native call in the library — VideoCapture, VideoWriter, CascadeClassifier.load, Dnn.readNet — and none of those has an in-memory equivalent to reroute through, so they remain ASCII-path-only on Windows.
==Ownership== A returned Managed[Mat] is caller-owned: nothing else holds a reference and nothing else will free it. Prefer Images.read(p).map(_.use(...)) over holding one. Mats created internally — the MatOfByte staging buffers, and the empty Mat a failed read hands back — are released here.
Attributes
- Source
- Images.scala
- Supertypes
-
class Objecttrait Matchableclass Any
- Self type
-
Images.type
How imread/imdecode should decode a pixel's colour.
How imread/imdecode should decode a pixel's colour.
Attributes
- Source
- Enums.scala
- Supertypes
-
trait Enumtrait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
Attributes
- Companion
- class
- Source
- Enums.scala
- Supertypes
-
trait Producttrait Mirrorclass Objecttrait Matchableclass Any
- Self type
-
ImreadFlags.type
Image reading flags — a total model, not a bitmask.
Image reading flags — a total model, not a bitmask.
OpenCV's IMREAD_* constants look like OR-able bits but are not: each IMREAD_REDUCED_* value already bakes in its colour bit, and IMREAD_UNCHANGED is -1, whose bits swamp everything else. OR-ing a colour with a reduced-size flag therefore silently decodes the wrong image. So the (colour, scale) pair maps totally onto exactly one named constant instead of composing, and only ignoreOrientation (bit 128) is a genuinely independent flag that may be OR-ed on top.
Reduced-size decode exists only for ImreadColor.Grayscale and ImreadColor.Color, and ImreadColor.Unchanged (-1) can carry no extra bit at all; the two requires reject the combinations OpenCV has no constant for, rather than quietly OR-ing them into something else.
Attributes
- Companion
- object
- Source
- Enums.scala
- Supertypes
-
trait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
The fraction of full resolution to decode at. OpenCV's reduced-size decode is cheaper than a full read followed by a resize, because the codec skips the discarded detail rather than producing it first.
The fraction of full resolution to decode at. OpenCV's reduced-size decode is cheaper than a full read followed by a resize, because the codec skips the discarded detail rather than producing it first.
Attributes
- Source
- Enums.scala
- Supertypes
-
trait Enumtrait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
Interpolation for resize and warps. A true enumeration.
Interpolation for resize and warps. A true enumeration.
Attributes
- Source
- Enums.scala
- Supertypes
-
trait Enumtrait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
A pinhole camera's intrinsics — what turns a pixel measurement into a metric one.
A pinhole camera's intrinsics — what turns a pixel measurement into a metric one.
fx/fy are the focal length in pixels, cx/cy the principal point (usually near the image centre). All calibration values must be finite; focal lengths must be positive. distortion is OpenCV's radial/tangential coefficients (k1, k2, p1, p2[, k3 …]); leave it empty for an ideal lens. Only the counts OpenCV itself accepts are allowed — see Intrinsics.ValidDistortionSizes. A real camera's numbers come from a chessboard calibration; when you have not calibrated, Intrinsics.approx gives a serviceable guess from the image size and a field-of-view estimate — good enough to see an augmented overlay track, not good enough to measure with.
This is the core camera model the vision layer builds on: scalacv.vision.Ar, HeadPose and Localizer all take an Intrinsics, scalacv.vision.Calibration produces one, and Image.undistort consumes one.
Attributes
- Companion
- object
- Source
- Intrinsics.scala
- Supertypes
-
trait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
Attributes
- Companion
- class
- Source
- Intrinsics.scala
- Supertypes
-
trait Producttrait Mirrorclass Objecttrait Matchableclass Any
- Self type
-
Intrinsics.type
Line rasterisation. A true enumeration.
Line rasterisation. A true enumeration.
Attributes
- Source
- Enums.scala
- Supertypes
-
trait Enumtrait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
Attributes
- Companion
- class
- Source
- Managed.scala
- Supertypes
-
class Objecttrait Matchableclass Any
- Self type
-
Managed.type
A native OpenCV object with a release that happens exactly once.
A native OpenCV object with a release that happens exactly once.
Two guarantees, both of which exist because getting them wrong is a JVM crash rather than an exception. Calling a method on a freed OpenCV object segfaults from native code — no stack trace, no catch, no test report; a double delete is undefined behaviour that merely often happens to survive. Measured, both.
- Release is a compare-and-set, so a second release is a no-op rather than a double free.
- Access after release throws
IllegalStateExceptionon the Scala side, before anything crosses JNI.
Prefer use over holding one of these. The scoped form is the only one where the compiler helps you.
==Diagnosing use-after-move==
The move semantics of Image mean the commonest mistake is reusing a handle a transform already consumed, and the resulting IllegalStateException fires at the reuse, which is rarely the interesting line. Start the JVM with -Dscalacv.trackOwnership=true and the exception carries, as its cause, the stack of the transform or terminal that actually spent the handle. It is off by default because it allocates a Throwable every time a handle is spent; the check that reads it lives only on the already-failing path, so a program that never misuses a handle pays nothing.
Attributes
- Companion
- object
- Source
- Managed.scala
- Supertypes
-
trait AutoCloseableclass Objecttrait Matchableclass Any
Helpers that do not belong on a Mat: the single place a destination Mat is allocated (Mats.produce), the shared greyscale reduction, small lifts between native memory and plain Scala data, and the named preconditions the ops enforce before crossing into native code.
Helpers that do not belong on a Mat: the single place a destination Mat is allocated (Mats.produce), the shared greyscale reduction, small lifts between native memory and plain Scala data, and the named preconditions the ops enforce before crossing into native code.
Attributes
- Source
- Mats.scala
- Supertypes
-
class Objecttrait Matchableclass Any
- Self type
-
Mats.type
Attributes
- Companion
- class
- Source
- Models.scala
- Supertypes
-
trait Producttrait Mirrorclass Objecttrait Matchableclass Any
- Self type
-
ModelSpec.type
A downloadable model file: its fixed name, the mirror URLs to try in order, the SHA-256 the fetched bytes must match, and optionally the exact size they must have.
A downloadable model file: its fixed name, the mirror URLs to try in order, the SHA-256 the fetched bytes must match, and optionally the exact size they must have.
Integrity checking is the default: build a spec with ModelSpec.apply and its pinned hash is verified on every download and on every cache hit. Skipping the check is a deliberate, named opt-out — ModelSpec.unverified — that loses the tamper/corruption guard, so reach for it only for a model with no published checksum.
sizeBytes is not redundant with the hash; it changes the message, and only ever in the direction of being more useful. The failure it catches is the common one: a mirror that answers a model request with an HTML error page, or a Git LFS host that serves a 131-byte pointer file, both with HTTP 200. Those hash wrong, of course — but "SHA-256 mismatch" invites the reader to suspect tampering, whereas "expected 232589 bytes, got 131" says what actually happened. It is also checked first, so it costs one stat rather than a full digest of a file that was never the model.
Attributes
- Companion
- object
- Source
- Models.scala
- Supertypes
-
trait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
A small registry and downloader for the model files scalacv's detectors need. It is the downloader: scalacv.vision.FaceDetect.downloadModel is a one-line alias for fetch(FaceDetect.modelSpec, into).
A small registry and downloader for the model files scalacv's detectors need. It is the downloader: scalacv.vision.FaceDetect.downloadModel is a one-line alias for fetch(FaceDetect.modelSpec, into).
fetch downloads to a temp file beside the target and moves it into place only after it verifies, so an interrupted run never leaves a truncated model for the next load to trip over. It is idempotent: a target that already exists (and, if a hash or size is pinned, still matches) is returned without touching the network. URLs may be http(s):// or file://, so a model you already have on disk is just another source.
The detector model specs live next to their detectors (scalacv.vision.FaceDetect.modelSpec and scalacv.vision.FaceRecognizer.modelSpec); supply your own ModelSpec for anything else.
Attributes
- Source
- Models.scala
- Supertypes
-
class Objecttrait Matchableclass Any
- Self type
-
Models.type
Compound morphological operations (morphologyEx). Erosion and dilation have their own methods.
Compound morphological operations (morphologyEx). Erosion and dilation have their own methods.
Attributes
- Source
- Enums.scala
- Supertypes
-
trait Enumtrait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
The structuring-element shape for morphology. A true enumeration.
The structuring-element shape for morphology. A true enumeration.
Attributes
- Source
- Enums.scala
- Supertypes
-
trait Enumtrait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
Loads the OpenCV native libraries, without ever requiring a GUI toolkit.
Loads the OpenCV native libraries, without ever requiring a GUI toolkit.
The obvious approach — Loader.load(classOf[opencv_java]) — does not work on a headless machine. javacpp eagerly initialises the whole preset graph, and opencv_highgui is GTK2-linked on Linux, so on a box without GTK it throws and takes objdetect, calib3d, features2d and video down with it. objdetect is precisely what this library needs most.
libopencv_java itself links no GUI toolkit. So we bring javacpp up through a GUI-free preset, extract the platform payload, and then load the JNI shim, resolving its dependencies on demand — see satisfy for why loading them speculatively is not merely wasteful but unsafe. The result needs no apt-get install libgtk2.0-0t64 on any runner.
Attributes
- Source
- OpenCv.scala
- Supertypes
-
class Objecttrait Matchableclass Any
- Self type
-
OpenCv.type
The destination depth for the operators that can change it — the derivative operators, and normalize.
The destination depth for the operators that can change it — the derivative operators, and normalize.
Worth a type of its own rather than a bare int because OutputDepth.SameAsSource is a trap on the commonest input: Sobel on an 8-bit unsigned image with ddepth = -1 clips every negative derivative to zero, so half of each edge silently disappears. OutputDepth.Signed16 then convertScaleAbs is the standard fix.
Attributes
- Source
- Ops.scala
- Supertypes
-
trait Enumtrait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
The two outputs of Mat.pencilSketchBoth: the colour sketch (3-channel) and the grey one (single-channel). A named pair rather than a tuple for the same reason Thresholded is one — the field names, not positions, say which plate is which. Both Mats are owned by the receiver of the pair and must be released independently.
The two outputs of Mat.pencilSketchBoth: the colour sketch (3-channel) and the grey one (single-channel). A named pair rather than a tuple for the same reason Thresholded is one — the field names, not positions, say which plate is which. Both Mats are owned by the receiver of the pair and must be released independently.
Attributes
- Source
- Effects.scala
- Supertypes
-
trait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
Which method OpenCV's solvePnP should use — the typed replacement for its SOLVEPNP_* int flags.
Which method OpenCV's solvePnP should use — the typed replacement for its SOLVEPNP_* int flags.
The choice is not cosmetic: each solver has its own degenerate-input behaviour (some answer ok = false, some abort with a native CV_Assert — see Pnp.solve), so the flag is part of a call site's error story and deserves a name, not a number. This is a subset of OpenCV's solvers, not its full catalog. See https://docs.opencv.org/4.x/d5/d1f/calib3d_solvePnP.html for each solver's point-count and geometry requirements; in particular, DLS and UPnP are fallback aliases in OpenCV, not distinct robust estimators.
Attributes
- Source
- Pnp.scala
- Supertypes
-
trait Enumtrait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
Attributes
- Companion
- class
- Source
- Geometry.scala
- Supertypes
-
trait Producttrait Mirrorclass Objecttrait Matchableclass Any
- Self type
-
Point.type
A 2D point in pixel coordinates, origin top-left, x right and y down — the sub-pixel form OpenCV uses for feature and contour work, so both fields are Double.
A 2D point in pixel coordinates, origin top-left, x right and y down — the sub-pixel form OpenCV uses for feature and contour work, so both fields are Double.
Attributes
- Companion
- object
- Source
- Geometry.scala
- Supertypes
-
trait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
Attributes
- Companion
- class
- Source
- Geometry.scala
- Supertypes
-
trait Producttrait Mirrorclass Objecttrait Matchableclass Any
- Self type
-
Point3.type
A point in 3D space — a model coordinate for scalacv.vision.Ar pose work, in the same units you give a marker's side length (metres is the usual choice). z points out of the marker plane toward the camera.
A point in 3D space — a model coordinate for scalacv.vision.Ar pose work, in the same units you give a marker's side length (metres is the usual choice). z points out of the marker plane toward the camera.
Attributes
- Companion
- object
- Source
- Geometry.scala
- Supertypes
-
trait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
A line in Hesse normal form, as HoughLines reports it: infinite, with no endpoints.
A line in Hesse normal form, as HoughLines reports it: infinite, with no endpoints.
The underlying Mat is CV_32FC2, but the fields are widened to Double at the decode boundary: every other measurement the library surfaces (Point, Contour) is a Double, and the float channels carry no precision past 24 bits for the widening to lose.
Value parameters
- rho
-
distance in pixels from the image origin (top-left) to the line, along the normal.
- theta
-
angle of that normal in radians. 0 is a vertical line,
Pi/2a horizontal one — the angle describes the normal, not the line, which is the usual source of confusion.
Attributes
- Source
- Hough.scala
- Supertypes
-
trait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
A PolarLine plus its accumulator score.
A PolarLine plus its accumulator score.
HoughLinesWithAccumulator exists precisely so the votes are visible; they are the only way to rank results, since the plain transform already returns them sorted but discards the magnitudes. Votes are whole numbers stored in a float channel, hence the narrowing to Int; rho and theta are widened to Double like PolarLine.
Attributes
- Source
- Hough.scala
- Supertypes
-
trait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
Writes Images to a video file — the counterpart to Camera for output.
A recorder is fixed at open time to one frame size, fps and codec; every frame written must match that size and be 8-bit. VideoWriter is one of the three OpenCV types with a real public release(), and the recorder is caller-owned — close it, or use Recorder.using.
Attributes
- Companion
- object
- Source
- Recorder.scala
- Supertypes
-
trait AutoCloseableclass Objecttrait Matchableclass Any
Attributes
- Companion
- class
- Source
- Recorder.scala
- Supertypes
-
class Objecttrait Matchableclass Any
- Self type
-
Recorder.type
An axis-aligned integer rectangle: top-left corner (x, y) and non-negative width/height. The origin may be negative (a region of interest can extend past the top-left of the image); the extent may not.
An axis-aligned integer rectangle: top-left corner (x, y) and non-negative width/height. The origin may be negative (a region of interest can extend past the top-left of the image); the extent may not.
Attributes
- Companion
- object
- Source
- Geometry.scala
- Supertypes
-
trait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
Attributes
- Companion
- class
- Source
- Geometry.scala
- Supertypes
-
trait Producttrait Mirrorclass Objecttrait Matchableclass Any
- Self type
-
Rect.type
How a native OpenCV object gets freed.
How a native OpenCV object gets freed.
There are two regimes, and which one applies is not a style choice — it is dictated by what the generated Java binding exposes. Of the 188 org.opencv.* types that hold a native pointer, exactly three have a public release(): Mat, org.opencv.videoio.VideoCapture and org.opencv.videoio.VideoWriter. The other 185 — including every detector this library wraps — expose only a private static native void delete(long) plus a finalize().
Relying on that finalize() is not viable. It is not disabled (a common myth), but it only runs when the collector runs, and the collector sees ~40 bytes of Java header per multi- megabyte native buffer. Measured: 2000 unreleased 1000x1000 Mats reach 5.8 GB RSS against 144 MB when released.
Attributes
- Companion
- object
- Source
- Releasable.scala
- Supertypes
-
class Objecttrait Matchableclass Any
Attributes
- Companion
- trait
- Source
- Releasable.scala
- Supertypes
-
class Objecttrait Matchableclass Any
- Self type
-
Releasable.type
An immutable rigid mapping between two 3D coordinate frames.
An immutable rigid mapping between two 3D coordinate frames.
Rotation is row-major and points are column vectors: x_destination = R * x_source + t. Coordinates and translation use the same caller-chosen units. There are no native resources to release. The rotation must be finite, 3×3, orthonormal and have determinant +1 (absolute tolerance 1e-8); translation must contain three finite values. Invalid construction, including copy, throws IllegalArgumentException. Inputs are immutable Scala sequences, not native matrix handles.
Attributes
- Companion
- object
- Source
- RigidTransform.scala
- Supertypes
-
trait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
Attributes
- Companion
- class
- Source
- RigidTransform.scala
- Supertypes
-
trait Producttrait Mirrorclass Objecttrait Matchableclass Any
- Self type
-
RigidTransform.type
Lossless quarter-turn rotations — no interpolation, exact pixels. A true enumeration.
Lossless quarter-turn rotations — no interpolation, exact pixels. A true enumeration.
Attributes
- Source
- Enums.scala
- Supertypes
-
trait Enumtrait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
A pixel value: up to four channel components, in whatever channel order the Mat uses. OpenCV's default is BGR, not RGB, so Scalar.Red is Scalar(0, 0, 255). Unset channels default to 0.
A pixel value: up to four channel components, in whatever channel order the Mat uses. OpenCV's default is BGR, not RGB, so Scalar.Red is Scalar(0, 0, 255). Unset channels default to 0.
Attributes
- Companion
- object
- Source
- Geometry.scala
- Supertypes
-
trait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
Attributes
- Companion
- class
- Source
- Geometry.scala
- Supertypes
-
trait Producttrait Mirrorclass Objecttrait Matchableclass Any
- Self type
-
Scalar.type
A line segment with real endpoints, as HoughLinesP reports it.
A line segment with real endpoints, as HoughLinesP reports it.
Integer, because the underlying Mat is CV_32SC4. Rounding here would invent precision OpenCV never produced.
Attributes
- Source
- Hough.scala
- Supertypes
-
trait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
A finite, non-negative width/height extent in pixels. Fractional extents are retained for geometry and text measurement; integer raster operations document their own rounding rule. Zero is an empty extent.
A finite, non-negative width/height extent in pixels. Fractional extents are retained for geometry and text measurement; integer raster operations document their own rounding rule. Zero is an empty extent.
Attributes
- Companion
- object
- Source
- Geometry.scala
- Supertypes
-
trait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
Attributes
- Companion
- class
- Source
- Geometry.scala
- Supertypes
-
trait Producttrait Mirrorclass Objecttrait Matchableclass Any
- Self type
-
Size.type
What a string will occupy once drawn, from Imgproc.getTextSize.
What a string will occupy once drawn, from Imgproc.getTextSize.
Value parameters
- baseline
-
how far the descenders reach below the baseline, in pixels. It is returned separately because
drawText's anchor is the baseline's left end, not the top-left corner: a background box has to besize.height + baselinetall to enclose the text, and forgetting it clips everygandy. - size
-
the bounding box of the glyphs.
Attributes
- Source
- Draw.scala
- Supertypes
-
trait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
How wide a stroke is, or that a shape is filled instead.
How wide a stroke is, or that a shape is filled instead.
OpenCV encodes "filled" as a thickness of -1, a sentinel that ordinary arithmetic on a thickness will happily produce by accident. Worse, it is only meaningful for closed shapes: cv::line asserts 0 < thickness, so passing the sentinel to a line or to text aborts in native code. Splitting the two cases into distinct types lets the shapes that can be filled accept Thickness while lines and text accept Thickness.Stroke only — the mistake stops compiling rather than crashing.
Attributes
- Companion
- object
- Source
- Draw.scala
- Supertypes
-
class Objecttrait Matchableclass Any
- Known subtypes
Attributes
- Companion
- trait
- Source
- Draw.scala
- Supertypes
-
trait Sumtrait Mirrorclass Objecttrait Matchableclass Any
- Self type
-
Thickness.type
Thresholding — a bitmask, not an enumeration.
Thresholding — a bitmask, not an enumeration.
Imgproc.threshold takes a mode OR-ed with at most one automatic-threshold modifier. Modelled as enum the useful combinations would be unrepresentable, and THRESH_MASK would leak into a public API where it means nothing.
Attributes
- Companion
- object
- Source
- Enums.scala
- Supertypes
-
trait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
Attributes
- Companion
- class
- Source
- Enums.scala
- Supertypes
-
trait Producttrait Mirrorclass Objecttrait Matchableclass Any
- Self type
-
Threshold.type
What threshold actually returns.
What threshold actually returns.
Imgproc.threshold returns a double that most wrappers discard. For Otsu and Triangle it is the threshold OpenCV chose — frequently the reason you called it at all.
Attributes
- Source
- Enums.scala
- Supertypes
-
trait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
The pair Mat.threshold returns: the thresholded image plus the value OpenCV computed.
The pair Mat.threshold returns: the thresholded image plus the value OpenCV computed.
Why a pair exists at all: for Threshold.Auto.Otsu and Threshold.Auto.Triangle the whole point of the call is the threshold OpenCV chose, so dropping the double the native function returns would throw away the answer. And why a named case class rather than the (Managed[Mat], ThresholdResult) tuple this used to be: a tuple made threshold the one op that did not return a bare Managed[Mat], which broke Managed.pipe and left every call site spelling ._1. A named pair destructures the same (val Thresholded(out, result) = ...) but reads as .image / .computed everywhere else.
Attributes
- Source
- Enums.scala
- Supertypes
-
trait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
Video capture: opening a source, and walking its frames without leaking one per iteration.
Video capture: opening a source, and walking its frames without leaking one per iteration.
==Why there is no frame LazyList==
The obvious shape for "the frames of a video" is a lazy sequence, and it is wrong here. LazyList memoises: once evaluated, a cell holds its head forever so that a second traversal is cheap. Applied to frames, that means every Mat the list has ever produced stays reachable — so either nothing is ever released (an unbounded native leak; a 1080p BGR frame is ~6 MB, so a minute at 30 fps is over 10 GB) or frames are released as they are consumed and the list is a field of dangling handles that the next traversal hands back as empty Mats. There is no version of the API where memoisation and per-frame release are both correct. Same argument, verbatim, for Stream, and for any Iterator combinator that retains what it has seen.
So the frame source here is an Iterator that owns exactly one Mat and decodes into it in place. It is created inside a scope, it is released when that scope ends, and it holds one frame's worth of native memory no matter how long the video is.
==The borrowing contract, enforced==
This is the one place in scalacv where a frame you are handed is not yours, and it is the exact opposite of the contract in Ops.scala. Each element is a BorrowedMat — a liveness-checked view over the iterator's single decode buffer, spent the moment the iterator advances or the frames block returns. Every access, including the BorrowedMat.mat escape hatch, throws IllegalStateException once the view is spent, so sequential retention of the view fails loudly. The raw Mat returned by .mat is checked only at extraction and remains unsafe to retain. Access must not overlap a pull or close on another thread/fiber: the liveness check is not a lock. Clone inside the loop before handing pixels to concurrent work.
- Do read the view, record it through
frame.mat, and run theOpsextensions overframe.mat: those allocate their own destination and never alias the receiver, soframe.mat.cvtColor(...)inside the loop is correct and yields a Mat you own. - Need to keep a frame?
frame.clone()inside the loop — the clone is caller-owned — or framesCopied, which does that per frame and hands you a Managed. it.toListstill compiles, but every element in the list is spent by the time you look at it: N spent views, not N frames.
Video.open("clip.mp4").map { capture =>
capture.use { c =>
Video.frames(c) { frames =>
frames.map(f => f.mat.cvtColor(ColorConversion.BgrToGray).use(_.findContours().size)).sum
}
}
}
==Exception mode==
VideoCapture.setExceptionMode(true) turns a silent false into a CvException carrying OpenCV's own message, and open uses it: a missing file becomes CvError.NativeCall quoting the path instead of a bare "it did not open". frames deliberately turns it off for the duration of the loop, because OpenCV reports end-of-file through the identical exception it uses for a broken stream — cap.cpp:533 error: (-2:Unspecified error) in function 'grab', measured on a clean five-frame file. With exception mode on there is no way to tell "the video ended" from "the camera was unplugged", so the loop would have to treat every real failure as a normal end. Off, read returning false ends the stream and a genuine decode error still surfaces as CvError.NativeCall.
Attributes
- Source
- Video.scala
- Supertypes
-
class Objecttrait Matchableclass Any
- Self type
-
Video.type
Extensions
Extensions
The standard Hough transform: every line is infinite and expressed in polar form.
The standard Hough transform: every line is infinite and expressed in polar form.
Value parameters
- maxTheta
-
upper bound on the reported angle, in radians.
- minTheta
-
lower bound on the reported angle, in radians.
- rho
-
accumulator distance resolution, in pixels.
- srn
-
divisor for a coarse-to-fine
rho;0(withstn) selects the classic transform. - stn
-
divisor for a coarse-to-fine
theta. - theta
-
accumulator angle resolution, in radians.
- threshold
-
minimum accumulator votes for a line to be reported.
Attributes
- Throws
-
IllegalArgumentException
if the receiver is not a non-empty 8-bit single-channel image.
- Source
- Hough.scala
The probabilistic Hough transform: finite segments with endpoints in image coordinates.
The probabilistic Hough transform: finite segments with endpoints in image coordinates.
Value parameters
- maxLineGap
-
largest gap, in pixels, that will still be bridged into one segment.
- minLineLength
-
segments shorter than this are discarded.
0keeps everything. - rho
-
accumulator distance resolution, in pixels.
- theta
-
accumulator angle resolution, in radians.
- threshold
-
minimum accumulator votes for a line to be reported.
Attributes
- Throws
-
IllegalArgumentException
if the receiver is not a non-empty 8-bit single-channel image.
- Source
- Hough.scala
As houghLines, but keeps each line's accumulator score.
As houghLines, but keeps each line's accumulator score.
Attributes
- Throws
-
IllegalArgumentException
if the receiver is not a non-empty 8-bit single-channel image.
- Source
- Hough.scala
Draws a line with an arrowhead at to. Mutates the receiver.
Draws a line with an arrowhead at to. Mutates the receiver.
Value parameters
- tipLength
-
the arrowhead's length as a fraction of the whole line, so the head stays in proportion however long the line is. OpenCV's own default is
0.1.
Attributes
- Source
- Draw.scala
Draws a circle of radius pixels about center. Mutates the receiver.
Draws every contour in contours. Mutates the receiver.
Draws every contour in contours. Mutates the receiver.
This is the renderer for what findContours returns. Thickness.Filled fills them, which is the usual way to turn a set of contours back into a mask.
Attributes
- Source
- Draw.scala
Draws a straight line from from to to. Mutates the receiver.
Draws a straight line from from to to. Mutates the receiver.
Coordinates outside the image are clipped, not rejected — that is OpenCV's behaviour and it is what makes drawing a detection that runs off the edge of a frame safe.
Attributes
- Source
- Draw.scala
Draws a connected run of line segments through points. Mutates the receiver.
Draws a connected run of line segments through points. Mutates the receiver.
Value parameters
- closed
-
whether to draw the closing edge from the last point back to the first. Defaults to
true, matching what Contour and polygon data mean. An emptypointsdraws nothing rather than failing: a polyline is frequently the result of a filter, and filtering everything out is a legitimate outcome, not a programming error.
Attributes
- Source
- Draw.scala
Draws an axis-aligned rectangle. Mutates the receiver.
Draws an axis-aligned rectangle. Mutates the receiver.
Pass Thickness.Filled for a solid block — useful as a label background or for building a mask.
Attributes
- Source
- Draw.scala
Draws every segment in segments. Mutates the receiver.
Draws every segment in segments. Mutates the receiver.
The renderer for houghLinesP, whose results are otherwise invisible.
Attributes
- Source
- Draw.scala
Draws text with its baseline's left end at at. Mutates the receiver.
Draws text with its baseline's left end at at. Mutates the receiver.
at is not the top-left corner: OpenCV anchors text on the baseline, so a y of 0 puts almost the whole string above the image and draws nothing visible. Draw.textSize gives the box to place it by.
Only the Hershey vector fonts exist — OpenCV cannot render a system font, and non-ASCII characters are drawn as ?.
Attributes
- Source
- Draw.scala
Fills the polygon described by points with color. Mutates the receiver.
Fills the polygon described by points with color. Mutates the receiver.
The outline is implicitly closed. Self-intersecting outlines are filled by OpenCV's even-odd rule.
Attributes
- Source
- Draw.scala
Finds contours in a binary image.
Finds contours in a binary image.
The input must be single-channel 8-bit (or CV_32SC1); anything else raises CvError.NativeCall. Unlike the C++ API this does not modify mat — the Java binding copies internally — but treating a thresholded image as consumed is still the safer habit.
Every MatOfPoint OpenCV allocates, and the hierarchy Mat it fills, are released before this returns. The hierarchy itself is not exposed: it is only meaningful for the nesting-aware retrieval modes, and handing back a raw Nx1 CV_32SC4 Mat of indices would be exactly the untyped, unmanaged shape this library exists to remove. A typed nesting API can be added later without breaking this one.
Value parameters
- approximation
-
how each outline is compressed. ContourApproximation.Simple collapses straight runs to their endpoints, so an axis-aligned rectangle comes back as 4 points rather than its full pixel chain.
- retrieval
-
which contours to return and how to relate them. Defaults to ContourRetrieval.External — outermost only, which is what callers who ignore the hierarchy almost always mean.
Attributes
- Returns
-
the contours, in OpenCV's order, as plain Scala data. Empty when the image is uniform.
- Source
- Contours.scala
Detects the dominant text skew and rotates the image upright — the classic OCR pre-step. Works on any image: it binarises internally to find the text pixels, fits a minimum-area rectangle to them, and rotates by that tilt. The exposed corners are filled white, and a detected skew beyond maxAngle is treated as a misread and left alone (a page of large graphics can fool the estimate).
Detects the dominant text skew and rotates the image upright — the classic OCR pre-step. Works on any image: it binarises internally to find the text pixels, fits a minimum-area rectangle to them, and rotates by that tilt. The exposed corners are filled white, and a detected skew beyond maxAngle is treated as a misread and left alone (a page of large graphics can fool the estimate).
Attributes
- Source
- Deskew.scala
Detail enhancement — boosts local contrast and texture. Needs 8-bit 3-channel input.
Detail enhancement — boosts local contrast and texture. Needs 8-bit 3-channel input.
Attributes
- Source
- Effects.scala
Edge-preserving smoothing — flattens texture while keeping edges (the basis of the painterly filters). Needs 8-bit 3-channel input.
Edge-preserving smoothing — flattens texture while keeping edges (the basis of the painterly filters). Needs 8-bit 3-channel input.
Attributes
- Source
- Effects.scala
Emboss, via a directional convolution.
Gamma correction: g < 1 darkens the mid-tones, g > 1 lifts them. Needs 8-bit 3-channel input — the same contract as its stylisation neighbours, enforced up front rather than as a CvError.NativeCall from Core.LUT on a float image.
Gamma correction: g < 1 darkens the mid-tones, g > 1 lifts them. Needs 8-bit 3-channel input — the same contract as its stylisation neighbours, enforced up front rather than as a CvError.NativeCall from Core.LUT on a float image.
Attributes
- Source
- Effects.scala
A colour pencil-sketch rendering. Needs 8-bit 3-channel input. The greyscale sketch OpenCV also computes is discarded — see pencilSketchBoth if you want it.
A colour pencil-sketch rendering. Needs 8-bit 3-channel input. The greyscale sketch OpenCV also computes is discarded — see pencilSketchBoth if you want it.
Attributes
- Source
- Effects.scala
Both halves of a pencil sketch: the colour rendering and the greyscale one OpenCV computes on the way — the colour plate and the grey plate of the same drawing. pencilSketch pays for the grey output and throws it away (the native call always fills both destinations); this overload exists for callers that want the grey sketch too, so the work is never wasted. Needs 8-bit 3-channel input.
Both halves of a pencil sketch: the colour rendering and the greyscale one OpenCV computes on the way — the colour plate and the grey plate of the same drawing. pencilSketch pays for the grey output and throws it away (the native call always fills both destinations); this overload exists for callers that want the grey sketch too, so the work is never wasted. Needs 8-bit 3-channel input.
Both Mats in the returned pair are owned by the caller and must be released independently.
Attributes
- Source
- Effects.scala
Posterises to levels tones per channel.
Adjusts saturation: factor > 1 is more vivid, < 1 toward grey, 0 fully grey (still 3-channel). Needs 8-bit 3-channel input.
Adjusts saturation: factor > 1 is more vivid, < 1 toward grey, 0 fully grey (still 3-channel). Needs 8-bit 3-channel input.
Attributes
- Source
- Effects.scala
Sepia tone, via a colour matrix. Needs 8-bit 3-channel input.
Stylisation — a smooth, painterly cartoon look via edge-aware smoothing. Needs 8-bit 3-channel input.
Stylisation — a smooth, painterly cartoon look via edge-aware smoothing. Needs 8-bit 3-channel input.
Attributes
- Source
- Effects.scala
Colour temperature: shift > 0 warms (more red), < 0 cools (more blue), in [-1, 1]. Needs 8-bit 3-channel input.
Colour temperature: shift > 0 warms (more red), < 0 cools (more blue), in [-1, 1]. Needs 8-bit 3-channel input.
Attributes
- Source
- Effects.scala
Absolute per-element difference |self - other|. other is borrowed. The basis of frame-difference motion detection — see scalacv.vision.MotionDetector.
Absolute per-element difference |self - other|. other is borrowed. The basis of frame-difference motion detection — see scalacv.vision.MotionDetector.
Attributes
- Source
- Ops.scala
Adaptive threshold — a threshold computed per neighbourhood rather than once for the whole image, which is what makes it hold up under uneven lighting (document scans, OCR pre-processing). CV_8UC1 only.
Adaptive threshold — a threshold computed per neighbourhood rather than once for the whole image, which is what makes it hold up under uneven lighting (document scans, OCR pre-processing). CV_8UC1 only.
mode is restricted to Threshold.Mode.Binary / Threshold.Mode.BinaryInv because OpenCV's adaptiveThreshold accepts exactly those two; it replaces the inverse: Boolean this parameter used to be — a boolean trap at the call site (inverse = true says nothing about what is inverted) when Threshold.Mode already models the distinction by name.
Value parameters
- blockSize
-
the neighbourhood side; must be odd and ≥ 3.
- c
-
a constant subtracted from the local mean/Gaussian — raise it to keep less.
Attributes
- Source
- Ops.scala
Weighted sum: self * alpha + other * beta + gamma.
Weighted sum: self * alpha + other * beta + gamma.
other is borrowed, exactly like the receiver — it is neither released nor aliased.
Attributes
- Source
- Ops.scala
Edge-preserving bilateral filter: smooths flat regions while keeping edges crisp. Markedly slower than a Gaussian. diameter ≤ 0 lets OpenCV derive it from sigmaSpace.
Edge-preserving bilateral filter: smooths flat regions while keeping edges crisp. Markedly slower than a Gaussian. diameter ≤ 0 lets OpenCV derive it from sigmaSpace.
Attributes
- Source
- Ops.scala
Bitwise NOT — inverts every pixel (255 - v for 8-bit).
Adds a border (padding) of the given pixel widths on each side.
Normalised box filter. anchor defaults to Point(-1, -1), OpenCV's spelling of "the kernel centre".
Normalised box filter. anchor defaults to Point(-1, -1), OpenCV's spelling of "the kernel centre".
Named boxBlur, not blur, on purpose: the high-level Image.blur is a radius-based Gaussian, and a mid-level method sharing that name would silently switch filter families (and output hash) the moment a caller drops from image.blur(2) to image.mat.blur(...). The two are different algorithms; the names say so.
border may not be BorderType.Wrap — see BorderType.requireFilterSupport.
Attributes
- Source
- Ops.scala
Canny edge detection. The result is always CV_8UC1 regardless of the source type.
Canny edge detection. The result is always CV_8UC1 regardless of the source type.
OpenCV accepts only 3, 5 and 7 for apertureSize — the Sobel aperture used internally — and aborts in native code for anything else, so it is checked here instead.
Attributes
- Source
- Ops.scala
Scales, takes the absolute value, and saturating-casts to 8-bit unsigned.
Converts between colour spaces. The channel count of the result follows the conversion, not the source.
Converts between colour spaces. The channel count of the result follows the conversion, not the source.
Attributes
- Source
- Ops.scala
Morphological dilation — grows bright regions, fills small dark gaps.
Histogram equalisation. OpenCV accepts CV_8UC1 only; anything else fails in native code.
Histogram equalisation. OpenCV accepts CV_8UC1 only; anything else fails in native code.
Attributes
- Source
- Ops.scala
Morphological erosion with a radius-derived structuring element — shrinks bright regions, removes small bright specks. iterations applies it repeatedly.
Morphological erosion with a radius-derived structuring element — shrinks bright regions, removes small bright specks. iterations applies it repeatedly.
Attributes
- Source
- Ops.scala
Extracts a single channel as its own image.
Gaussian blur.
Gaussian blur.
kernel may be Size(0, 0), in which case OpenCV derives the kernel from the sigmas; otherwise both extents must be positive and odd. A sigmaY of 0 means "same as sigmaX", which is OpenCV's own default and not a degenerate value.
border may not be BorderType.Wrap — see BorderType.requireFilterSupport.
Attributes
- Source
- Ops.scala
A binary mask (CV_8UC1, 0 or 255) of the pixels whose every channel lies within [lo, hi]. The core of colour segmentation — usually run on an HSV image. lo must not exceed hi in any channel; checked here, per extractChannel's index precheck, because OpenCV reports an inverted range only as an empty mask — a plausible-looking result that is silently wrong.
A binary mask (CV_8UC1, 0 or 255) of the pixels whose every channel lies within [lo, hi]. The core of colour segmentation — usually run on an HSV image. lo must not exceed hi in any channel; checked here, per extractChannel's index precheck, because OpenCV reports an inverted range only as an empty mask — a plausible-looking result that is silently wrong.
Attributes
- Source
- Ops.scala
Inpaints the region under mask (CV_8UC1, non-zero = repair) from its surroundings — remove a scratch, an object, or a watermark. mask is borrowed.
Inpaints the region under mask (CV_8UC1, non-zero = repair) from its surroundings — remove a scratch, an object, or a watermark. mask is borrowed.
Attributes
- Source
- Ops.scala
Laplacian. kernelSize of 1 is the 3x3 aperture OpenCV special-cases, and is its default.
Laplacian. kernelSize of 1 is the 3x3 aperture OpenCV special-cases, and is its default.
border may not be BorderType.Wrap — see BorderType.requireFilterSupport.
Attributes
- Source
- Ops.scala
Keeps this image only where mask (CV_8UC1) is non-zero; the rest becomes black. mask is borrowed.
Keeps this image only where mask (CV_8UC1) is non-zero; the rest becomes black. mask is borrowed.
Attributes
- Source
- Ops.scala
Median blur — each pixel becomes the median of its ksize×ksize neighbourhood. The standard cure for salt-and-pepper noise, and unlike a Gaussian it does not smear edges. ksize must be odd and ≥ 3.
Median blur — each pixel becomes the median of its ksize×ksize neighbourhood. The standard cure for salt-and-pepper noise, and unlike a Gaussian it does not smear edges. ksize must be odd and ≥ 3.
Attributes
- Source
- Ops.scala
Linearly rescales values into [alpha, beta] (min-max normalisation) and hands the result back at depth. Useful for stretching contrast, and the standard way of bringing a non-8-bit result — a disparity map, a distance transform, a float Sobel response — into a displayable range.
Linearly rescales values into [alpha, beta] (min-max normalisation) and hands the result back at depth. Useful for stretching contrast, and the standard way of bringing a non-8-bit result — a disparity map, a distance transform, a float Sobel response — into a displayable range.
depth defaults to OutputDepth.Unsigned8 rather than to OpenCV's own dtype = -1, which means "same depth as the source". With -1 a CV_32F input rescaled to [0, 255] comes back as a CV_32F holding the values 0..255, so the second half of the job — making it displayable — never happened: Image.toBufferedImage rejects it, applyColorMap (colorMap) aborts in native code because it takes CV_8UC1/CV_8UC3 only, and imwrite only survives it by silently coercing behind our back. For an already-8-bit source Unsigned8 and -1 are the same conversion, so a plain contrast stretch is unaffected by the default.
Pass OutputDepth.SameAsSource for a stretch that must keep the source's precision — rescaling a float image into [0, 1] for a model's input, for instance, where 8-bit would collapse the range onto 256 levels.
Attributes
- Source
- Ops.scala
Resizes to an absolute size, given here as a Size whose two Double extents are truncated toward zero on the way into native code: Size(1.9, 1.9) asks for a 1×1 image.
Resizes to an absolute size, given here as a Size whose two Double extents are truncated toward zero on the way into native code: Size(1.9, 1.9) asks for a 1×1 image.
That truncation is why the check below is on the truncated integers and not on the doubles. A computed target such as Size(width * factor, height * factor) with a small factor lands between 0 and 1, which is positive as a Double but empty as a cv::Size, and OpenCV then aborts with CV_Assert(inv_scale_x > 0) — a CvError.NativeCall quoting a C++ expression, in place of the IllegalArgumentException naming the caller's own argument that this file promises for a zero target size. Checking after truncation is what Mats.requireKernel already does for kernels.
Attributes
- Source
- Ops.scala
Rotates by an arbitrary angle (degrees, counter-clockwise) about the centre, expanding the canvas so no corner is clipped. scale zooms at the same time. The exposed border is filled per border.
Rotates by an arbitrary angle (degrees, counter-clockwise) about the centre, expanding the canvas so no corner is clipped. scale zooms at the same time. The exposed border is filled per border.
The fill is named color here just as in border, and the Constant default — where the filters default to BorderType.Reflect101 — is deliberate: a filter reflects so the kernel's support region stays inside the image content, which avoids edge ringing; a geometric transform exposes pixels that were never in the frame at all, and there a reflected or replicated edge would smear the image's own content into the border. A constant outside colour (black, or white for a scanned page) reads as background instead.
Attributes
- Source
- Ops.scala
Resizes by independent x and y scale factors. Rejects a pair of factors that would round this Mat's own size down to an empty one.
Resizes by independent x and y scale factors. Rejects a pair of factors that would round this Mat's own size down to an empty one.
A separate method rather than an overload because OpenCV distinguishes the two modes by passing Size(0, 0) — a sentinel that has no business in a typed API.
Positive factors are not on their own enough to know the call is legal: OpenCV derives the destination from the receiver as cvRound(cols * fx) × cvRound(rows * fy) and then asserts !dsize.empty(), so shrinking a small image hard enough (a 100-pixel sprite at fx = 0.005) dies in native code. The check therefore has to be against the receiver's extent, not against the factors.
math.rint and not .toInt or math.round, because cvRound rounds half to even: on a 100-wide source fx = 0.006 legitimately yields a 1-pixel result that truncation would reject, and fx = 0.025 yields 2 where math.round says 3. Note the asymmetry with resize, where the destination arrives as a cv::Size and is truncated instead — the two native paths genuinely round differently, so one shared rule would be wrong for one of them.
Attributes
- Source
- Ops.scala
Seamlessly clones this image (the foreground object) into background at center, blending gradients so the paste is invisible (Poisson editing). mask (CV_8UC1) marks the object; background and mask are borrowed. The result is background-sized.
Seamlessly clones this image (the foreground object) into background at center, blending gradients so the paste is invisible (Poisson editing). mask (CV_8UC1) marks the object; background and mask are borrowed. The result is background-sized.
Attributes
- Source
- Ops.scala
Unsharp-mask sharpening: adds back amount × (image − its blur). amount 0 is a no-op; ~1 is a firm sharpen. Overdo it and haloes appear at edges.
Unsharp-mask sharpening: adds back amount × (image − its blur). amount 0 is a no-op; ~1 is a firm sharpen. Overdo it and haloes appear at edges.
Attributes
- Source
- Ops.scala
Sobel derivative.
Sobel derivative.
See OutputDepth before leaving depth at its default on an 8-bit image. border may not be BorderType.Wrap — see BorderType.requireFilterSupport.
Attributes
- Source
- Ops.scala
Thresholding.
Thresholding.
Returns a Thresholded — the thresholded image and the double OpenCV computed. Most wrappers drop that number; for Threshold.Auto.Otsu and Threshold.Auto.Triangle it is the threshold OpenCV chose, which is frequently the reason the call was made. For a fixed threshold it is just value handed back. A named pair, not a tuple, so .image chains with pipe like every other op.
Imgproc.threshold has a single 5-argument overload with no defaults, so every argument is spelled out here rather than being layered over Java defaults that do not exist.
Attributes
- Source
- Ops.scala
Removes lens distortion using calibrated camera Intrinsics — the barrel/pincushion bend a real lens adds is mapped back out, so straight edges in the world come back straight. A no-op (a plain copy) when intrinsics.distortion is empty. See scalacv.vision.Calibration.
Removes lens distortion using calibrated camera Intrinsics — the barrel/pincushion bend a real lens adds is mapped back out, so straight edges in the world come back straight. A no-op (a plain copy) when intrinsics.distortion is empty. See scalacv.vision.Calibration.
Attributes
- Source
- Ops.scala
Hands the wrapped Mat to f and releases it once f has produced its own result.
Hands the wrapped Mat to f and releases it once f has produced its own result.
This is the whole reason the ownership contract above is safe to write down. Each op returns a Mat the caller owns, so a chain of them produces one owned Mat per stage, and every stage but the last is garbage the moment the next one returns. pipe makes that the default rather than something the caller has to remember: self is consumed, and using it afterwards throws IllegalStateException instead of reading freed memory.
val edges = src.gaussianBlur(Size(5, 5), 1.5).pipe(_.canny(50, 150))
The release happens in a finally, so a stage that throws does not leak its input either. For a terminal stage that produces something other than a Mat — a count, a Seq[Rect] — use Managed.use, which has the same shape and the same guarantee.
Attributes
- Source
- Ops.scala