HAL llamada a un método de flujo Análisis OpenCV

HAL llamada a un método de flujo Análisis OpenCV

Hay algunos en OpenCV llamada HAL (Hardware de aceleración Layer) para lograr, y parece ver el hardware nombre asociado, de hecho, no todos pueden entenderse como más rápido que la versión convencional de la OCV suficiente. En este artículo se tiene que hacer es encontrar o cortado en sus procesos de implementación, las llamadas de función para obtener a través de toda la lógica. Esta será resize, y GaussianBlurdos funciones para analizar.

cambio de tamaño

En primer lugar localizar el módulo de imgproc imgproc.hpp archivo, que encontrar CV_EXPORTS_W void resize( InputArray src, OutputArray dst, Size dsize, double fx = 0, double fy = 0, int interpolation = INTER_LINEAR );métodos. Porque todos estamos referencia en el archivo de cabecera para su uso cuando fuera usado, que es una función de los archivos de cabecera es que utilizamos la función de importación. El OCV se dan cuenta que habrá una gran cantidad de ramas, es difícil de determinar, por lo que llegamos a es más conveniente de la entrada. Luego salta a la implementación de la función, si no soporta IDE, en una lata correspondiente resize.cpp misma función declaración de la función se realiza correspondiente a la función de búsqueda, de la siguiente manera:

void cv::resize( InputArray _src, OutputArray _dst, Size dsize,
                 double inv_scale_x, double inv_scale_y, int interpolation )
{
    CV_INSTRUMENT_REGION();

    Size ssize = _src.size();

    CV_Assert( !ssize.empty() );
    if( dsize.empty() )
    {
        CV_Assert(inv_scale_x > 0); CV_Assert(inv_scale_y > 0);
        dsize = Size(saturate_cast<int>(ssize.width*inv_scale_x),
                     saturate_cast<int>(ssize.height*inv_scale_y));
        CV_Assert( !dsize.empty() );
    }
    else
    {
        inv_scale_x = (double)dsize.width/ssize.width;
        inv_scale_y = (double)dsize.height/ssize.height;
        CV_Assert(inv_scale_x > 0); CV_Assert(inv_scale_y > 0);
    }

    if (interpolation == INTER_LINEAR_EXACT && (_src.depth() == CV_32F || _src.depth() == CV_64F))
        interpolation = INTER_LINEAR; // If depth isn't supported fallback to generic resize

    CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat() && _src.cols() > 10 && _src.rows() > 10,
               ocl_resize(_src, _dst, dsize, inv_scale_x, inv_scale_y, interpolation))

    Mat src = _src.getMat();
    _dst.create(dsize, src.type());
    Mat dst = _dst.getMat();

    if (dsize == ssize)
    {
        // Source and destination are of same size. Use simple copy.
        src.copyTo(dst);
        return;
    }

    hal::resize(src.type(), src.data, src.step, src.cols, src.rows, dst.data, dst.step, dst.cols, dst.rows, inv_scale_x, inv_scale_y, interpolation);
}

Vemos que la realización función hace tres cosas:

  1. verificación de los parámetros
  2. Detectar si el soporte OpenCL o habilitar
  3. Utilizar el espacio de la función de cambio de tamaño para lograr hal

Hal saltar a lograr, que también se encuentra resize.cpp , parte del código:

namespace hal {

void resize(int src_type,
            const uchar * src_data, size_t src_step, int src_width, int src_height,
            uchar * dst_data, size_t dst_step, int dst_width, int dst_height,
            double inv_scale_x, double inv_scale_y, int interpolation)
{
    CV_INSTRUMENT_REGION();

    CV_Assert((dst_width > 0 && dst_height > 0) || (inv_scale_x > 0 && inv_scale_y > 0));
    if (inv_scale_x < DBL_EPSILON || inv_scale_y < DBL_EPSILON)
    {
        inv_scale_x = static_cast<double>(dst_width) / src_width;
        inv_scale_y = static_cast<double>(dst_height) / src_height;
    }

    CALL_HAL(resize, cv_hal_resize, src_type, src_data, src_step, src_width, src_height, dst_data, dst_step, dst_width, dst_height, inv_scale_x, inv_scale_y, interpolation);
    //剩下部分代码是常规实现

Entonces vemos aquí tienen CALL_HALcomo una macro, saltar a su realización, que se encuentra hal_replacement.hpp ,

#define CALL_HAL(name, fun, ...) \
    int res = __CV_EXPAND(fun(__VA_ARGS__)); \
    if (res == CV_HAL_ERROR_OK) \
        return; \
    else if (res != CV_HAL_ERROR_NOT_IMPLEMENTED) \
        CV_Error_(cv::Error::StsInternal, \
            ("HAL implementation " CVAUX_STR(name) " ==> " CVAUX_STR(fun) " returned %d (0x%08x)", res, res));

Podemos ver que en realidad se llama a la funfunción, si se devuelve la función CV_HAL_ERROR_OK, será return, obviamente, hal::resizetambién vuelve, de lo contrario, las llamadas CV_Error_, este no es el final del programa y hacer que la función anormal o como directa por terminada la función entera, más adelante entrar en detalles. De todos modos, el resultado es que usted va a hal::resizecontinuar hacia abajo por debajo de la implementación convencional, y no sólo en esta macro return.
Luego hal_replacement.hpp encontramos cv_hal_resizedefine como

#define cv_hal_resize hal_ni_resize

A continuación, seguir buscando la hal_ni_resizerealización de

inline int hal_ni_resize(int src_type, const uchar *src_data, size_t src_step, int src_width, int src_height, uchar *dst_data, size_t dst_step, int dst_width, int dst_height, double inv_scale_x, double inv_scale_y, int interpolation) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }

Aquí, nos encontramos con que la función para volver directamente CV_HAL_ERROR_NOT_IMPLEMENTED, de acuerdo con el análisis anterior, hal::resizecontinuar hacia abajo. Por lo tanto, para lograr hal es ¿cómo es que cortar?
Hemos encontrado que, hal_replacement.hpp de CALL_HALla macro tiene una #include "custom_hal.hpp"buena extraña, no incluir generalmente al principio de cosas? A continuación nos fijamos en este custom_hal.cpp , se encontró sólo una frase #include "carotene/tegra_hal.hpp", seguimos rastrear. Dado que las funciones analizadas anteriormente es hal_ni_resizedirectamente la Búsqueda hal_ni_resize, en vano. Luego tenemos la Búsqueda cv_hal_resize, encontrado:

#undef cv_hal_resize
#define cv_hal_resize TEGRA_RESIZE

De repente sensación muy rápida, conseguir a través, y hasta aquí para cv_hal_resizedar undef cabo, sabemos hal_replacement.hpp es #define cv_hal_resize hal_ni_resize, y la ubicación del archivo desde el punto de vista, esto no def def ser, entonces redefinido TEGRA_RESIZE, encontrar, hallazgo su definición:

#define TEGRA_RESIZE(src_type, src_data, src_step, src_width, src_height, dst_data, dst_step, dst_width, dst_height, inv_scale_x, inv_scale_y, interpolation) \
( \
    interpolation == CV_HAL_INTER_LINEAR ? \
        CV_MAT_DEPTH(src_type) == CV_8U && CAROTENE_NS::isResizeLinearOpenCVSupported(CAROTENE_NS::Size2D(src_width, src_height), CAROTENE_NS::Size2D(dst_width, dst_height), ((src_type >> CV_CN_SHIFT) + 1)) && \
        inv_scale_x > 0 && inv_scale_y > 0 && \
        (dst_width - 0.5)/inv_scale_x - 0.5 < src_width && (dst_height - 0.5)/inv_scale_y - 0.5 < src_height && \
        (dst_width + 0.5)/inv_scale_x + 0.5 >= src_width && (dst_height + 0.5)/inv_scale_y + 0.5 >= src_height && \
        std::abs(dst_width / inv_scale_x - src_width) < 0.1 && std::abs(dst_height / inv_scale_y - src_height) < 0.1 ? \
            CAROTENE_NS::resizeLinearOpenCV(CAROTENE_NS::Size2D(src_width, src_height), CAROTENE_NS::Size2D(dst_width, dst_height), \
                                            src_data, src_step, dst_data, dst_step, 1.0/inv_scale_x, 1.0/inv_scale_y, ((src_type >> CV_CN_SHIFT) + 1)), \
            CV_HAL_ERROR_OK : CV_HAL_ERROR_NOT_IMPLEMENTED : \
    interpolation == CV_HAL_INTER_AREA ? \
        CV_MAT_DEPTH(src_type) == CV_8U && CAROTENE_NS::isResizeAreaSupported(1.0/inv_scale_x, 1.0/inv_scale_y, ((src_type >> CV_CN_SHIFT) + 1)) && \
        std::abs(dst_width / inv_scale_x - src_width) < 0.1 && std::abs(dst_height / inv_scale_y - src_height) < 0.1 ? \
            CAROTENE_NS::resizeAreaOpenCV(CAROTENE_NS::Size2D(src_width, src_height), CAROTENE_NS::Size2D(dst_width, dst_height), \
                                          src_data, src_step, dst_data, dst_step, 1.0/inv_scale_x, 1.0/inv_scale_y, ((src_type >> CV_CN_SHIFT) + 1)), \
            CV_HAL_ERROR_OK : CV_HAL_ERROR_NOT_IMPLEMENTED : \
    /*nearest neighbour interpolation disabled due to rounding accuracy issues*/ \
    /*interpolation == CV_HAL_INTER_NEAREST ? \
        (src_type == CV_8UC1 || src_type == CV_8SC1) && CAROTENE_NS::isResizeNearestNeighborSupported(CAROTENE_NS::Size2D(src_width, src_height), 1) ? \
            CAROTENE_NS::resizeNearestNeighbor(CAROTENE_NS::Size2D(src_width, src_height), CAROTENE_NS::Size2D(dst_width, dst_height), \
                                               src_data, src_step, dst_data, dst_step, 1.0/inv_scale_x, 1.0/inv_scale_y, 1), \
            CV_HAL_ERROR_OK : \
        (src_type == CV_8UC3 || src_type == CV_8SC3) && CAROTENE_NS::isResizeNearestNeighborSupported(CAROTENE_NS::Size2D(src_width, src_height), 3) ? \
            CAROTENE_NS::resizeNearestNeighbor(CAROTENE_NS::Size2D(src_width, src_height), CAROTENE_NS::Size2D(dst_width, dst_height), \
                                               src_data, src_step, dst_data, dst_step, 1.0/inv_scale_x, 1.0/inv_scale_y, 3), \
            CV_HAL_ERROR_OK : \
        (src_type == CV_8UC4 || src_type == CV_8SC4 || src_type == CV_16UC2 || src_type == CV_16SC2 || src_type == CV_32SC1) && \
        CAROTENE_NS::isResizeNearestNeighborSupported(CAROTENE_NS::Size2D(src_width, src_height), 4) ? \
            CAROTENE_NS::resizeNearestNeighbor(CAROTENE_NS::Size2D(src_width, src_height), CAROTENE_NS::Size2D(dst_width, dst_height), \
                                               src_data, src_step, dst_data, dst_step, 1.0/inv_scale_x, 1.0/inv_scale_y, 4), \
            CV_HAL_ERROR_OK : CV_HAL_ERROR_NOT_IMPLEMENTED :*/ \
    CV_HAL_ERROR_NOT_IMPLEMENTED \
)

Esta definición de la macro, probablemente, hacer lo siguiente:

  1. Si la interpolación bilineal para el tipo de datos CV_8U y tamaño, y los canales de cumplir con ciertos requisitos, entonces resizeLinearOpenCVir a cambiar el tamaño de verdad, y vuelve CV_HAL_ERROR_OK, la interpolación bilineal no cumple con estas condiciones no son compatibles con el retorno CV_HAL_ERROR_NOT_IMPLEMENTED, también lo hará tomar hal::resizeconciencia común
  2. Si la interpolación ÁREA, la interpolación bilineal y la situación es similar
  3. Otro método de interpolación no es compatible actualmente. Pero desde el punto de vista de estos comentarios de código, los planes deben ser apoyados, pero ahora no sólo hacen un trabajo bueno.
    Esta macro definiciones utilizadas observaron con poca frecuencia que el operador de coma para alcanzar CV_HAL_ERROR_OKel valor de retorno, vuelve operador coma el valor de su extremo derecho.
    Entonces podemos saltar a resizeLinearOpenCV, y resizeAreaOpenCVpara realizar un seguimiento real de implementación rápida de.

Se puede encontrar, es que la clave para cortar la UNDEF y definir las operaciones.

Desenfoque gaussiano

Del mismo modo, en smooth.cpp que se encuentra en la cv_hal_gaussianBluraplicación del método, encontramos macro hal cv_hal_gaussianBlur, y luego a la tegra_hal.hppde la Búsqueda cv_hal_gaussianBlury no se encontraron resultados. Esto demuestra hal rápido desenfoque gaussiano versión sin correspondiente. A continuación, busque la biblioteca caroteno ha relacionado desenfoque gaussiano código, parece que no debe tenerse en cuenta? Nos éxito el registro escribiendo demostración y el código fuente de una manera, encontramos que estas funciones no se dan cuenta que se llama, es en CALL_HALuna macro para volver allí en CV_HAL_ERROR_NOT_IMPLEMENTEDel. Estas implementaciones deben ser lo suficientemente bueno, así que no se cortó en ella, espere lentamente por ella.

Supongo que te gusta

Origin www.cnblogs.com/willhua/p/12521581.html
Recomendado
Clasificación