Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在矩阵中搜索c+中不同行或列旁边的最小值和最大值的最快方法是什么+;_C++_Algorithm_Opencv - Fatal编程技术网

C++ 在矩阵中搜索c+中不同行或列旁边的最小值和最大值的最快方法是什么+;

C++ 在矩阵中搜索c+中不同行或列旁边的最小值和最大值的最快方法是什么+;,c++,algorithm,opencv,C++,Algorithm,Opencv,假设我需要在矩阵中搜索行和列以找到最小值,那么最好的方法是什么 我现在能想到的是有两个嵌套向量,如下所示: std::vector<std::vector<float>> myData; 但是对于在cols上搜索,我需要编写一个for循环来进行搜索 // col search say on col 20 float min_value=10000000; / assuming values in table are less than this value in

假设我需要在矩阵中搜索行和列以找到最小值,那么最好的方法是什么

我现在能想到的是有两个嵌套向量,如下所示:

std::vector<std::vector<float>> myData;
但是对于在cols上搜索,我需要编写一个for循环来进行搜索

 // col search say on col 20
 float min_value=10000000;  / assuming values in table are less than this value
 int min_index=-1;
 for(int i=0;i<myData.size();++i)
 {
       if(myData[i][20] <min_value)
       {
            min_value=myData[i][20];
            min_index=i;
        }
  }
//列搜索在列20上说
浮动最小值=10000000;/假设表中的值小于此值
int min_指数=-1;

对于(int i=0;i,由于您的结构元素将发生变化,您最好的选择是使用(又称芬威克树)实现范围最小查询()。我建议您为每行和每列保留一棵这样的树。如果您希望支持对原始矩阵的子矩阵的查询,也可以实现这样的树的树。我建议的解决方案需要
O(N*M)
额外的内存,其中N和M是矩阵的维度。它还将支持查询和更新的复杂性
O(log(N)+log(M))

虽然这可能比您希望的更复杂,但可以对进行子类化。这里有一个简单的示例。您可以重新定义运算符以遍历列。这样,您可以像行迭代器一样将其传递到min_元素。

如果您有OpenCV Mat,则可以使用:

返回值
minVal/maxVal
包含实际值,而
minLoc/maxLoc
是最小/最大值的坐标(如果有多个值,则第一次出现)

显然,如果你传递整个矩阵,你会得到全局最小值/最大值,但你也可以只传递一行或一列

对于矩阵
C
,您可以使用

或对于行
m
,使用


Mat::col
Mat::row
都是
O(1)
操作,因为它们不复制任何数据,但我没有做任何基准测试来确定它们的列迭代有多快。

如果我理解正确,您希望能够找到给定矩阵的最小值和最大值(以及位置):

  • 全球
  • 在一行中
  • 一栏
  • 那么以下内容可能会对您有所帮助。让我们首先看看输出:

    mat = 
    [75, 97, 66, 95, 15, 22;
     24, 21, 71, 72, 34, 66;
     21, 69, 88, 72, 64, 1;
     26, 47, 26, 40, 95, 24;
     70, 37, 9, 83, 16, 83]
    
    global min =   1 @ [5, 2]
    global max =  97 @ [1, 0]
    
    Row 0 min =  15 @ [4, 0] max =  97 @ [1, 0]
    Row 1 min =  21 @ [1, 1] max =  72 @ [3, 1]
    Row 2 min =   1 @ [5, 2] max =  88 @ [2, 2]
    Row 3 min =  24 @ [5, 3] max =  95 @ [4, 3]
    Row 4 min =   9 @ [2, 4] max =  83 @ [3, 4]
    
    Col 0 min =  21 @ [0, 2] max =  75 @ [0, 0]
    Col 1 min =  21 @ [1, 1] max =  97 @ [1, 0]
    Col 2 min =   9 @ [2, 4] max =  88 @ [2, 2]
    Col 3 min =  40 @ [3, 3] max =  95 @ [3, 0]
    Col 4 min =  15 @ [4, 0] max =  95 @ [4, 3]
    Col 5 min =   1 @ [5, 2] max =  83 @ [5, 4]
    
    以及相应的代码(您说过可以使用OpenCV):

    #包括
    #包括
    #包括
    #包括
    名称空间{
    模板
    std::pairfindMinMaxLoc(cv::Mat\ux&Mat)
    {
    双重忽略1,忽略2;
    std::pairmmloc;
    cv::minMaxLoc(mat,&ignored1,&ignored2,&mmloc.first,&mmloc.second));
    返回mmloc;
    }
    模板
    std::pairminMaxLocRow(cv::Mat_&Mat,int-row)
    {
    cv::Rect roi(0,行,mat.size().宽度,1);
    cv::Mat_u-matRow=Mat(投资回报率);
    std::pairmmloc=findMinMaxLoc(matRow);
    mmloc.first.y=行;
    mmloc.second.y=行;
    返回mmloc;
    }
    模板
    std::pairminMaxLocCol(cv::Mat_&Mat,int col)
    {
    cv::Rect roi(col、0、1、mat.size().高度);
    cv::Mat_u-matCol=Mat(投资回报率);
    std::pairmmloc=findMinMaxLoc(matCol);
    mmloc.first.x=列;
    mmloc.second.x=列;
    返回mmloc;
    }
    }//名称空间
    int main(int argc,字符**argv)
    {
    //生成一个充满随机数据的矩阵。
    cv::大小(6,5);
    cv::Mat1i mat(尺寸);//或cv::Mat1b、cv::Mat3f等。
    cv::RNG RNG(cv::getcputiccount());
    rng.填充(材料,cv::rng::均匀,0,100);
    
    std::cout我们可以对行/列最小值/最大值使用
    cv::reduce
    (),而不是对range/roi使用
    minMaxLoc

    unsigned char data[4][2] = { 1,2,3,4,5,6,7,8 };
    Mat img(4, 2, CV_8UC1, data) ;
    
    Mat rowMinImg;
    int singleCoumnResult = 1;
    cv::reduce(img, rowMinImg, singleCoumnResult, CV_REDUCE_MIN );
    
    //Mat colMinImg;
    //int singleRowResult = 0;
    //cv::reduce(img, colMinImg, singleRowResult, CV_REDUCE_MIN );
    

    快速查看cv::reduce()的实现,表明查找最小值/最大值是一个简单的for循环。因此,如果您的数据已经存在于OpenCV
    Mat
    中,我认为这是一种方法。

    您的矩阵是动态变化的还是静态的?当我要计算最小值时,大小是已知的,但在编译过程中,大小是未知的。最快的方法是分配将矩阵作为一个连续的向量,并按顺序迭代。如果在构造时大小是固定的,那就是要做的。@Alex这会给我全局最小值,但我需要每行或每列旁边的最小值。我的意思是,值是否会动态变化?是否有一个y解决方案使用cv::Mat并易于使用和修改实施?我不知道有这样的解决方案,我也从未使用过cv::MatThis给出整个矩阵的最小值/最大值,但我对特定行/列旁边的最小值/最大值感兴趣。对不起,我不理解您对“旁边”一词的用法在本文中。好的,在阅读了一些其他答案后,您可能正在查找给定行或列的最小/最大值。我将更新我的答案。
    minMaxLoc(C.col(n), &minVal, &maxVal, &minLoc, &maxLoc);
    
    minMaxLoc(C.row(m), &minVal, &maxVal, &minLoc, &maxLoc);
    
    mat = 
    [75, 97, 66, 95, 15, 22;
     24, 21, 71, 72, 34, 66;
     21, 69, 88, 72, 64, 1;
     26, 47, 26, 40, 95, 24;
     70, 37, 9, 83, 16, 83]
    
    global min =   1 @ [5, 2]
    global max =  97 @ [1, 0]
    
    Row 0 min =  15 @ [4, 0] max =  97 @ [1, 0]
    Row 1 min =  21 @ [1, 1] max =  72 @ [3, 1]
    Row 2 min =   1 @ [5, 2] max =  88 @ [2, 2]
    Row 3 min =  24 @ [5, 3] max =  95 @ [4, 3]
    Row 4 min =   9 @ [2, 4] max =  83 @ [3, 4]
    
    Col 0 min =  21 @ [0, 2] max =  75 @ [0, 0]
    Col 1 min =  21 @ [1, 1] max =  97 @ [1, 0]
    Col 2 min =   9 @ [2, 4] max =  88 @ [2, 2]
    Col 3 min =  40 @ [3, 3] max =  95 @ [3, 0]
    Col 4 min =  15 @ [4, 0] max =  95 @ [4, 3]
    Col 5 min =   1 @ [5, 2] max =  83 @ [5, 4]
    
    #include <opencv2/core/core.hpp>
    
    #include <algorithm>
    #include <iostream>
    #include <iomanip>
    
    namespace {
    
    template <typename T>
    std::pair< cv::Point, cv::Point > findMinMaxLoc( cv::Mat_<T> & mat )
    {
        double ignored1, ignored2;
        std::pair< cv::Point, cv::Point > mmloc;
        cv::minMaxLoc( mat, &ignored1, &ignored2, &(mmloc.first), &(mmloc.second) );
    
        return mmloc;
    }
    
    template <typename T>
    std::pair< cv::Point, cv::Point > minMaxLocRow( cv::Mat_<T> & mat, int row )
    {
        cv::Rect roi( 0, row, mat.size().width, 1 );
        cv::Mat_<T> matRow = mat( roi );
    
        std::pair< cv::Point, cv::Point > mmloc = findMinMaxLoc( matRow );
        mmloc.first.y  = row;
        mmloc.second.y = row;
    
        return mmloc;
    }
    
    template <typename T>
    std::pair< cv::Point, cv::Point > minMaxLocCol( cv::Mat_<T> & mat, int col )
    {
        cv::Rect roi( col, 0, 1, mat.size().height  );
        cv::Mat_<T> matCol = mat( roi );
    
        std::pair< cv::Point, cv::Point > mmloc = findMinMaxLoc( matCol );
        mmloc.first.x  = col;
        mmloc.second.x = col;
    
        return mmloc;
    }
    
    } // namespace
    
    int main( int argc, char ** argv )
    {
        // Generate a matrix filled with random data.
        cv::Size size( 6, 5 );
        cv::Mat1i mat( size ); // Or cv::Mat1b, cv::Mat3f, etc.
        cv::RNG rng( cv::getCPUTickCount() );
    
        rng.fill( mat, cv::RNG::UNIFORM, 0, 100 );
    
        std::cout << "mat = " << std::endl << mat << std::endl << std::endl;
    
        // Find the global minimum and maximum.
        std::pair< cv::Point, cv::Point > mmloc = findMinMaxLoc( mat );
    
        std::cout << "global min = " << std::setw( 3 ) << std::setfill( ' ' );
        std::cout << mat( mmloc.first )  << " @ " << mmloc.first  << std::endl;
        std::cout << "global max = " << std::setw( 3 ) << std::setfill( ' ' );
        std::cout << mat( mmloc.second ) << " @ " << mmloc.second << std::endl << std::endl;
    
        // Row-wise extrema.
        for ( int row = 0; row < size.height; ++row )
        {
            std::pair< cv::Point, cv::Point > mmloc = minMaxLocRow( mat, row );
    
            std::cout << "Row " << row;
            std::cout << " min = " << std::setw( 3 ) << std::setfill( ' ' );
            std::cout << mat( mmloc.first )  << " @ " << mmloc.first;
            std::cout << " max = " << std::setw( 3 ) << std::setfill( ' ' );
            std::cout << mat( mmloc.second ) << " @ " << mmloc.second << std::endl;
        }
        std::cout << std::endl;
    
        // Column-wise extrema.
        for ( int col = 0; col < size.width; ++col )
        {
            std::pair< cv::Point, cv::Point > mmloc = minMaxLocCol( mat, col );
    
            std::cout << "Col " << col;
            std::cout << " min = " << std::setw( 3 ) << std::setfill( ' ' );
            std::cout << mat( mmloc.first )  << " @ " << mmloc.first;
            std::cout << " max = " << std::setw( 3 ) << std::setfill( ' ' );
            std::cout << mat( mmloc.second ) << " @ " << mmloc.second << std::endl;
        }
    
        return 0;
    }
    
    unsigned char data[4][2] = { 1,2,3,4,5,6,7,8 };
    Mat img(4, 2, CV_8UC1, data) ;
    
    Mat rowMinImg;
    int singleCoumnResult = 1;
    cv::reduce(img, rowMinImg, singleCoumnResult, CV_REDUCE_MIN );
    
    //Mat colMinImg;
    //int singleRowResult = 0;
    //cv::reduce(img, colMinImg, singleRowResult, CV_REDUCE_MIN );