import cv2
import cv2.typing
import typing


# Enumerations
FEATURE_SET_COMPUTE_10: int
FEATURE_SET_COMPUTE_11: int
FEATURE_SET_COMPUTE_12: int
FEATURE_SET_COMPUTE_13: int
FEATURE_SET_COMPUTE_20: int
FEATURE_SET_COMPUTE_21: int
FEATURE_SET_COMPUTE_30: int
FEATURE_SET_COMPUTE_32: int
FEATURE_SET_COMPUTE_35: int
FEATURE_SET_COMPUTE_50: int
GLOBAL_ATOMICS: int
SHARED_ATOMICS: int
NATIVE_DOUBLE: int
WARP_SHUFFLE_FUNCTIONS: int
DYNAMIC_PARALLELISM: int
FeatureSet = int
"""One of [FEATURE_SET_COMPUTE_10, FEATURE_SET_COMPUTE_11, FEATURE_SET_COMPUTE_12, FEATURE_SET_COMPUTE_13, FEATURE_SET_COMPUTE_20, FEATURE_SET_COMPUTE_21, FEATURE_SET_COMPUTE_30, FEATURE_SET_COMPUTE_32, FEATURE_SET_COMPUTE_35, FEATURE_SET_COMPUTE_50, GLOBAL_ATOMICS, SHARED_ATOMICS, NATIVE_DOUBLE, WARP_SHUFFLE_FUNCTIONS, DYNAMIC_PARALLELISM]"""


HostMem_PAGE_LOCKED: int
HOST_MEM_PAGE_LOCKED: int
HostMem_SHARED: int
HOST_MEM_SHARED: int
HostMem_WRITE_COMBINED: int
HOST_MEM_WRITE_COMBINED: int
HostMem_AllocType = int
"""One of [HostMem_PAGE_LOCKED, HOST_MEM_PAGE_LOCKED, HostMem_SHARED, HOST_MEM_SHARED, HostMem_WRITE_COMBINED, HOST_MEM_WRITE_COMBINED]"""

Event_DEFAULT: int
EVENT_DEFAULT: int
Event_BLOCKING_SYNC: int
EVENT_BLOCKING_SYNC: int
Event_DISABLE_TIMING: int
EVENT_DISABLE_TIMING: int
Event_INTERPROCESS: int
EVENT_INTERPROCESS: int
Event_CreateFlags = int
"""One of [Event_DEFAULT, EVENT_DEFAULT, Event_BLOCKING_SYNC, EVENT_BLOCKING_SYNC, Event_DISABLE_TIMING, EVENT_DISABLE_TIMING, Event_INTERPROCESS, EVENT_INTERPROCESS]"""

DeviceInfo_ComputeModeDefault: int
DEVICE_INFO_COMPUTE_MODE_DEFAULT: int
DeviceInfo_ComputeModeExclusive: int
DEVICE_INFO_COMPUTE_MODE_EXCLUSIVE: int
DeviceInfo_ComputeModeProhibited: int
DEVICE_INFO_COMPUTE_MODE_PROHIBITED: int
DeviceInfo_ComputeModeExclusiveProcess: int
DEVICE_INFO_COMPUTE_MODE_EXCLUSIVE_PROCESS: int
DeviceInfo_ComputeMode = int
"""One of [DeviceInfo_ComputeModeDefault, DEVICE_INFO_COMPUTE_MODE_DEFAULT, DeviceInfo_ComputeModeExclusive, DEVICE_INFO_COMPUTE_MODE_EXCLUSIVE, DeviceInfo_ComputeModeProhibited, DEVICE_INFO_COMPUTE_MODE_PROHIBITED, DeviceInfo_ComputeModeExclusiveProcess, DEVICE_INFO_COMPUTE_MODE_EXCLUSIVE_PROCESS]"""


# Classes
class GpuMat:
    @property
    def step(self) -> int: ...

    # Classes
    class Allocator:
        ...


    # Functions
    @typing.overload
    def __init__(self, allocator: GpuMat.Allocator = ...) -> None: ...
    @typing.overload
    def __init__(self, rows: int, cols: int, type: int, allocator: GpuMat.Allocator = ...) -> None: ...
    @typing.overload
    def __init__(self, size: cv2.typing.Size, type: int, allocator: GpuMat.Allocator = ...) -> None: ...
    @typing.overload
    def __init__(self, rows: int, cols: int, type: int, s: cv2.typing.Scalar, allocator: GpuMat.Allocator = ...) -> None: ...
    @typing.overload
    def __init__(self, size: cv2.typing.Size, type: int, s: cv2.typing.Scalar, allocator: GpuMat.Allocator = ...) -> None: ...
    @typing.overload
    def __init__(self, m: GpuMat) -> None: ...
    @typing.overload
    def __init__(self, m: GpuMat, rowRange: cv2.typing.Range, colRange: cv2.typing.Range) -> None: ...
    @typing.overload
    def __init__(self, m: GpuMat, roi: cv2.typing.Rect) -> None: ...
    @typing.overload
    def __init__(self, arr: cv2.typing.MatLike, allocator: GpuMat.Allocator = ...) -> None: ...
    @typing.overload
    def __init__(self, arr: GpuMat, allocator: GpuMat.Allocator = ...) -> None: ...
    @typing.overload
    def __init__(self, arr: cv2.UMat, allocator: GpuMat.Allocator = ...) -> None: ...

    @staticmethod
    def defaultAllocator() -> GpuMat.Allocator: ...

    @staticmethod
    def setDefaultAllocator(allocator: GpuMat.Allocator) -> None: ...

    @typing.overload
    def create(self, rows: int, cols: int, type: int) -> None: ...
    @typing.overload
    def create(self, size: cv2.typing.Size, type: int) -> None: ...

    def release(self) -> None: ...

    def swap(self, mat: GpuMat) -> None: ...

    @typing.overload
    def upload(self, arr: cv2.typing.MatLike) -> None: ...
    @typing.overload
    def upload(self, arr: GpuMat) -> None: ...
    @typing.overload
    def upload(self, arr: cv2.UMat) -> None: ...
    @typing.overload
    def upload(self, arr: cv2.typing.MatLike, stream: Stream) -> None: ...
    @typing.overload
    def upload(self, arr: GpuMat, stream: Stream) -> None: ...
    @typing.overload
    def upload(self, arr: cv2.UMat, stream: Stream) -> None: ...

    @typing.overload
    def download(self, dst: cv2.typing.MatLike | None = ...) -> cv2.typing.MatLike: ...
    @typing.overload
    def download(self, dst: GpuMat | None = ...) -> GpuMat: ...
    @typing.overload
    def download(self, dst: cv2.UMat | None = ...) -> cv2.UMat: ...
    @typing.overload
    def download(self, stream: Stream, dst: cv2.typing.MatLike | None = ...) -> cv2.typing.MatLike: ...
    @typing.overload
    def download(self, stream: Stream, dst: GpuMat | None = ...) -> GpuMat: ...
    @typing.overload
    def download(self, stream: Stream, dst: cv2.UMat | None = ...) -> cv2.UMat: ...

    def clone(self) -> GpuMat: ...

    @typing.overload
    def copyTo(self, dst: cv2.typing.MatLike | None = ...) -> cv2.typing.MatLike: ...
    @typing.overload
    def copyTo(self, dst: GpuMat | None = ...) -> GpuMat: ...
    @typing.overload
    def copyTo(self, dst: cv2.UMat | None = ...) -> cv2.UMat: ...
    @typing.overload
    def copyTo(self, stream: Stream, dst: cv2.typing.MatLike | None = ...) -> cv2.typing.MatLike: ...
    @typing.overload
    def copyTo(self, stream: Stream, dst: GpuMat | None = ...) -> GpuMat: ...
    @typing.overload
    def copyTo(self, stream: Stream, dst: cv2.UMat | None = ...) -> cv2.UMat: ...
    @typing.overload
    def copyTo(self, mask: cv2.typing.MatLike, dst: cv2.typing.MatLike | None = ...) -> cv2.typing.MatLike: ...
    @typing.overload
    def copyTo(self, mask: GpuMat, dst: GpuMat | None = ...) -> GpuMat: ...
    @typing.overload
    def copyTo(self, mask: cv2.UMat, dst: cv2.UMat | None = ...) -> cv2.UMat: ...
    @typing.overload
    def copyTo(self, mask: cv2.typing.MatLike, stream: Stream, dst: cv2.typing.MatLike | None = ...) -> cv2.typing.MatLike: ...
    @typing.overload
    def copyTo(self, mask: GpuMat, stream: Stream, dst: GpuMat | None = ...) -> GpuMat: ...
    @typing.overload
    def copyTo(self, mask: cv2.UMat, stream: Stream, dst: cv2.UMat | None = ...) -> cv2.UMat: ...

    @typing.overload
    def setTo(self, s: cv2.typing.Scalar) -> GpuMat: ...
    @typing.overload
    def setTo(self, s: cv2.typing.Scalar, stream: Stream) -> GpuMat: ...
    @typing.overload
    def setTo(self, s: cv2.typing.Scalar, mask: cv2.typing.MatLike) -> GpuMat: ...
    @typing.overload
    def setTo(self, s: cv2.typing.Scalar, mask: GpuMat) -> GpuMat: ...
    @typing.overload
    def setTo(self, s: cv2.typing.Scalar, mask: cv2.UMat) -> GpuMat: ...
    @typing.overload
    def setTo(self, s: cv2.typing.Scalar, mask: cv2.typing.MatLike, stream: Stream) -> GpuMat: ...
    @typing.overload
    def setTo(self, s: cv2.typing.Scalar, mask: GpuMat, stream: Stream) -> GpuMat: ...
    @typing.overload
    def setTo(self, s: cv2.typing.Scalar, mask: cv2.UMat, stream: Stream) -> GpuMat: ...

    @typing.overload
    def convertTo(self, rtype: int, dst: cv2.typing.MatLike | None = ...) -> cv2.typing.MatLike: ...
    @typing.overload
    def convertTo(self, rtype: int, dst: GpuMat | None = ...) -> GpuMat: ...
    @typing.overload
    def convertTo(self, rtype: int, dst: cv2.UMat | None = ...) -> cv2.UMat: ...
    @typing.overload
    def convertTo(self, rtype: int, stream: Stream, dst: cv2.typing.MatLike | None = ...) -> cv2.typing.MatLike: ...
    @typing.overload
    def convertTo(self, rtype: int, stream: Stream, dst: GpuMat | None = ...) -> GpuMat: ...
    @typing.overload
    def convertTo(self, rtype: int, stream: Stream, dst: cv2.UMat | None = ...) -> cv2.UMat: ...
    @typing.overload
    def convertTo(self, rtype: int, alpha: float, dst: cv2.typing.MatLike | None = ..., beta: float = ...) -> cv2.typing.MatLike: ...
    @typing.overload
    def convertTo(self, rtype: int, alpha: float, dst: GpuMat | None = ..., beta: float = ...) -> GpuMat: ...
    @typing.overload
    def convertTo(self, rtype: int, alpha: float, dst: cv2.UMat | None = ..., beta: float = ...) -> cv2.UMat: ...
    @typing.overload
    def convertTo(self, rtype: int, alpha: float, stream: Stream, dst: cv2.typing.MatLike | None = ...) -> cv2.typing.MatLike: ...
    @typing.overload
    def convertTo(self, rtype: int, alpha: float, stream: Stream, dst: GpuMat | None = ...) -> GpuMat: ...
    @typing.overload
    def convertTo(self, rtype: int, alpha: float, stream: Stream, dst: cv2.UMat | None = ...) -> cv2.UMat: ...
    @typing.overload
    def convertTo(self, rtype: int, alpha: float, beta: float, stream: Stream, dst: cv2.typing.MatLike | None = ...) -> cv2.typing.MatLike: ...
    @typing.overload
    def convertTo(self, rtype: int, alpha: float, beta: float, stream: Stream, dst: GpuMat | None = ...) -> GpuMat: ...
    @typing.overload
    def convertTo(self, rtype: int, alpha: float, beta: float, stream: Stream, dst: cv2.UMat | None = ...) -> cv2.UMat: ...

    def assignTo(self, m: GpuMat, type: int = ...) -> None: ...

    def row(self, y: int) -> GpuMat: ...

    def col(self, x: int) -> GpuMat: ...

    @typing.overload
    def rowRange(self, startrow: int, endrow: int) -> GpuMat: ...
    @typing.overload
    def rowRange(self, r: cv2.typing.Range) -> GpuMat: ...

    @typing.overload
    def colRange(self, startcol: int, endcol: int) -> GpuMat: ...
    @typing.overload
    def colRange(self, r: cv2.typing.Range) -> GpuMat: ...

    def reshape(self, cn: int, rows: int = ...) -> GpuMat: ...

    def locateROI(self, wholeSize: cv2.typing.Size, ofs: cv2.typing.Point) -> None: ...

    def adjustROI(self, dtop: int, dbottom: int, dleft: int, dright: int) -> GpuMat: ...

    def isContinuous(self) -> bool: ...

    def elemSize(self) -> int: ...

    def elemSize1(self) -> int: ...

    def type(self) -> int: ...

    def depth(self) -> int: ...

    def channels(self) -> int: ...

    def step1(self) -> int: ...

    def size(self) -> cv2.typing.Size: ...

    def empty(self) -> bool: ...

    def cudaPtr(self) -> cv2.typing.IntPointer: ...

    def updateContinuityFlag(self) -> None: ...


class GpuData:
    ...

class GpuMatND:
    ...

class BufferPool:
    # Functions
    def __init__(self, stream: Stream) -> None: ...

    @typing.overload
    def getBuffer(self, rows: int, cols: int, type: int) -> GpuMat: ...
    @typing.overload
    def getBuffer(self, size: cv2.typing.Size, type: int) -> GpuMat: ...

    def getAllocator(self) -> GpuMat.Allocator: ...


class HostMem:
    @property
    def step(self) -> int: ...

    # Functions
    @typing.overload
    def __init__(self, alloc_type: HostMem_AllocType = ...) -> None: ...
    @typing.overload
    def __init__(self, rows: int, cols: int, type: int, alloc_type: HostMem_AllocType = ...) -> None: ...
    @typing.overload
    def __init__(self, size: cv2.typing.Size, type: int, alloc_type: HostMem_AllocType = ...) -> None: ...
    @typing.overload
    def __init__(self, arr: cv2.typing.MatLike, alloc_type: HostMem_AllocType = ...) -> None: ...
    @typing.overload
    def __init__(self, arr: GpuMat, alloc_type: HostMem_AllocType = ...) -> None: ...
    @typing.overload
    def __init__(self, arr: cv2.UMat, alloc_type: HostMem_AllocType = ...) -> None: ...

    def swap(self, b: HostMem) -> None: ...

    def clone(self) -> HostMem: ...

    def create(self, rows: int, cols: int, type: int) -> None: ...

    def reshape(self, cn: int, rows: int = ...) -> HostMem: ...

    def createMatHeader(self) -> cv2.typing.MatLike: ...

    def isContinuous(self) -> bool: ...

    def elemSize(self) -> int: ...

    def elemSize1(self) -> int: ...

    def type(self) -> int: ...

    def depth(self) -> int: ...

    def channels(self) -> int: ...

    def step1(self) -> int: ...

    def size(self) -> cv2.typing.Size: ...

    def empty(self) -> bool: ...


class Stream:
    # Functions
    @typing.overload
    def __init__(self) -> None: ...
    @typing.overload
    def __init__(self, allocator: GpuMat.Allocator) -> None: ...
    @typing.overload
    def __init__(self, cudaFlags: int) -> None: ...

    def queryIfComplete(self) -> bool: ...

    def waitForCompletion(self) -> None: ...

    def waitEvent(self, event: Event) -> None: ...

    @classmethod
    def Null(cls) -> Stream: ...

    def cudaPtr(self) -> cv2.typing.IntPointer: ...


class Event:
    # Functions
    def __init__(self, flags: Event_CreateFlags = ...) -> None: ...

    def record(self, stream: Stream = ...) -> None: ...

    def queryIfComplete(self) -> bool: ...

    def waitForCompletion(self) -> None: ...

    @staticmethod
    def elapsedTime(start: Event, end: Event) -> float: ...


class TargetArchs:
    # Functions
    @staticmethod
    def has(major: int, minor: int) -> bool: ...

    @staticmethod
    def hasPtx(major: int, minor: int) -> bool: ...

    @staticmethod
    def hasBin(major: int, minor: int) -> bool: ...

    @staticmethod
    def hasEqualOrLessPtx(major: int, minor: int) -> bool: ...

    @staticmethod
    def hasEqualOrGreater(major: int, minor: int) -> bool: ...

    @staticmethod
    def hasEqualOrGreaterPtx(major: int, minor: int) -> bool: ...

    @staticmethod
    def hasEqualOrGreaterBin(major: int, minor: int) -> bool: ...


class DeviceInfo:
    # Functions
    @typing.overload
    def __init__(self) -> None: ...
    @typing.overload
    def __init__(self, device_id: int) -> None: ...

    def deviceID(self) -> int: ...

    def totalGlobalMem(self) -> int: ...

    def sharedMemPerBlock(self) -> int: ...

    def regsPerBlock(self) -> int: ...

    def warpSize(self) -> int: ...

    def memPitch(self) -> int: ...

    def maxThreadsPerBlock(self) -> int: ...

    def maxThreadsDim(self) -> cv2.typing.Vec3i: ...

    def maxGridSize(self) -> cv2.typing.Vec3i: ...

    def clockRate(self) -> int: ...

    def totalConstMem(self) -> int: ...

    def majorVersion(self) -> int: ...

    def minorVersion(self) -> int: ...

    def textureAlignment(self) -> int: ...

    def texturePitchAlignment(self) -> int: ...

    def multiProcessorCount(self) -> int: ...

    def kernelExecTimeoutEnabled(self) -> bool: ...

    def integrated(self) -> bool: ...

    def canMapHostMemory(self) -> bool: ...

    def computeMode(self) -> DeviceInfo_ComputeMode: ...

    def maxTexture1D(self) -> int: ...

    def maxTexture1DMipmap(self) -> int: ...

    def maxTexture1DLinear(self) -> int: ...

    def maxTexture2D(self) -> cv2.typing.Vec2i: ...

    def maxTexture2DMipmap(self) -> cv2.typing.Vec2i: ...

    def maxTexture2DLinear(self) -> cv2.typing.Vec3i: ...

    def maxTexture2DGather(self) -> cv2.typing.Vec2i: ...

    def maxTexture3D(self) -> cv2.typing.Vec3i: ...

    def maxTextureCubemap(self) -> int: ...

    def maxTexture1DLayered(self) -> cv2.typing.Vec2i: ...

    def maxTexture2DLayered(self) -> cv2.typing.Vec3i: ...

    def maxTextureCubemapLayered(self) -> cv2.typing.Vec2i: ...

    def maxSurface1D(self) -> int: ...

    def maxSurface2D(self) -> cv2.typing.Vec2i: ...

    def maxSurface3D(self) -> cv2.typing.Vec3i: ...

    def maxSurface1DLayered(self) -> cv2.typing.Vec2i: ...

    def maxSurface2DLayered(self) -> cv2.typing.Vec3i: ...

    def maxSurfaceCubemap(self) -> int: ...

    def maxSurfaceCubemapLayered(self) -> cv2.typing.Vec2i: ...

    def surfaceAlignment(self) -> int: ...

    def concurrentKernels(self) -> bool: ...

    def ECCEnabled(self) -> bool: ...

    def pciBusID(self) -> int: ...

    def pciDeviceID(self) -> int: ...

    def pciDomainID(self) -> int: ...

    def tccDriver(self) -> bool: ...

    def asyncEngineCount(self) -> int: ...

    def unifiedAddressing(self) -> bool: ...

    def memoryClockRate(self) -> int: ...

    def memoryBusWidth(self) -> int: ...

    def l2CacheSize(self) -> int: ...

    def maxThreadsPerMultiProcessor(self) -> int: ...

    def queryMemory(self, totalMemory: int, freeMemory: int) -> None: ...

    def freeMemory(self) -> int: ...

    def totalMemory(self) -> int: ...

    def isCompatible(self) -> bool: ...



# Functions
@typing.overload
def createContinuous(rows: int, cols: int, type: int, arr: cv2.typing.MatLike | None = ...) -> cv2.typing.MatLike: ...
@typing.overload
def createContinuous(rows: int, cols: int, type: int, arr: GpuMat | None = ...) -> GpuMat: ...
@typing.overload
def createContinuous(rows: int, cols: int, type: int, arr: cv2.UMat | None = ...) -> cv2.UMat: ...

@typing.overload
def createGpuMatFromCudaMemory(rows: int, cols: int, type: int, cudaMemoryAddress: int, step: int = ...) -> GpuMat: ...
@typing.overload
def createGpuMatFromCudaMemory(size: cv2.typing.Size, type: int, cudaMemoryAddress: int, step: int = ...) -> GpuMat: ...

@typing.overload
def ensureSizeIsEnough(rows: int, cols: int, type: int, arr: cv2.typing.MatLike | None = ...) -> cv2.typing.MatLike: ...
@typing.overload
def ensureSizeIsEnough(rows: int, cols: int, type: int, arr: GpuMat | None = ...) -> GpuMat: ...
@typing.overload
def ensureSizeIsEnough(rows: int, cols: int, type: int, arr: cv2.UMat | None = ...) -> cv2.UMat: ...

def fastNlMeansDenoising(src: GpuMat, h: float, dst: GpuMat | None = ..., search_window: int = ..., block_size: int = ..., stream: Stream = ...) -> GpuMat: ...

def fastNlMeansDenoisingColored(src: GpuMat, h_luminance: float, photo_render: float, dst: GpuMat | None = ..., search_window: int = ..., block_size: int = ..., stream: Stream = ...) -> GpuMat: ...

def getCudaEnabledDeviceCount() -> int: ...

def getDevice() -> int: ...

def nonLocalMeans(src: GpuMat, h: float, dst: GpuMat | None = ..., search_window: int = ..., block_size: int = ..., borderMode: int = ..., stream: Stream = ...) -> GpuMat: ...

def printCudaDeviceInfo(device: int) -> None: ...

def printShortCudaDeviceInfo(device: int) -> None: ...

def registerPageLocked(m: cv2.typing.MatLike) -> None: ...

def resetDevice() -> None: ...

def setBufferPoolConfig(deviceId: int, stackSize: int, stackCount: int) -> None: ...

def setBufferPoolUsage(on: bool) -> None: ...

def setDevice(device: int) -> None: ...

def unregisterPageLocked(m: cv2.typing.MatLike) -> None: ...

def wrapStream(cudaStreamMemoryAddress: int) -> Stream: ...


