前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >图像直线分析和拟合工具——opencv

图像直线分析和拟合工具——opencv

作者头像
vv彭
发布于 2020-12-16 08:45:25
发布于 2020-12-16 08:45:25
1.2K00
代码可运行
举报
文章被收录于专栏:c#学习笔记c#学习笔记
运行总次数:0
代码可运行

之前见过别人利用halcon封装了一个不错的函数叫drawRake好像是这个名字。这个工具挺好用的,可以在图像上随意画一条直线,然后设置一些参数,他就能在你画的这条线附近寻找你想要的直线, 然而其不是开源的,halcon也是收费的。于是我就心血来潮想自己做一个类似的工具,花了一天搞出来了,经过测试,效果还是杠杠的。下面介绍给大家,并会提供该工具函数的源码。

图像处理过程中我们有时候要对摄像头采集的图像进行直线分析,如果利用opencv分析的话,我们常常要自己建个工程,然后利用一些检测直线的算法,比如霍夫变换等,然而这样比较耗时。这个工具就可以即时的对图像直线进行分析。接下来给出这个工具函数的原型。名字我也取为drawRake。如下:

  1. std::vector<cv::Point2d> drawRake( cv::Mat &f,
  2. cv::Point2d pStart,
  3. cv::Point2d pEnd,
  4. int gap,
  5. int searchLength,
  6. int threshValue,
  7. bool isJudgeByGreatThan = false);

参数解析:

cv::Mat &f:图像数据,须为3通道或者单通道图像。

cv::Point2d pStart:指定直线的起点(这个是我们指定的,直线的起点和终点将被指定为搜索区域,我下面做的这个软件使用鼠标画线来指定直线)。

cv::Point2d pEnd:指定直线的终点。

int gap:搜索间隙(指定直线的细分步长)。

int searchLength:搜索长度,搜索范围。

int threshValue:搜索阈值。

bool isJudgeByGreatThan:目标点是否判决于大于阈值

返回值:std::vector<cv::Point2d>:一些列目标点集,用于直线拟合。

------------------------------------------------------------------------------------------

可能不大好理解这几个参数的定义,先来看看下面几个直观的图像吧!如下图:是摄像头实时采集的一帧图像数据,然后我们现在要分析下图黑色箭头所示的直线。

我们只需要在图像上的该直线附近画一条差不多直线,这条画上去的直线就是上面的输入参数的cv::Point2d pStart,cv::Point2d pEnd。效果如下图所示,因为是相机的实时帧,所以他会实时分析该直线,可以调节gap,searchLength,threshValue,isJudgeByGreatThan来分析最适合的直线。

如上图,我们看到一堆的小箭头,那个就是点集的搜索方向。现在看到的那一堆箭头比较密集是由于gap值比较小的原因。如果我们把gap变大,就会看到这一群箭头变得稀疏了,如下图所示:

我们看到箭头变稀疏了,因为gap增大了,我们还可以改变箭头的长度,他的意义就是输入参数searchLength,即搜索范围,他会从箭尾搜索到箭头,知道索引到符合的点,我们可以增大searchLength,就可以增加搜索范围,相应的箭头也会变长,如下图:

我们再分析一下别的直线,也很容易的找到该直线如下所示:

我们再来分析一下输入参数isJudgeByGreatThan,如果是FALSE的话就是从亮到暗(阈值是下限)搜索,如上图,如果设置成TRUE的话,就是从暗到亮搜索(阈值是上限),比如我们来分析一下纸箱盖子的直线,如下图。

好了,差不多直观的了解完了,接下来就是上代码。

------------------------------------------------------------------------------------------

下面是drawRake函数源码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
std::vector<cv::Point2d> drawRake(cv::Mat &f, cv::Point2d pStart, cv::Point2d pEnd, int gap, int searchLength, int threshValue, bool isJudgeByGreatThan){
 
        // 初始化内存
        std::vector<cv::Point2d> pVec; pVec.clear();    // rake点集
        double k = 0., b = 0., xConst = 0.;                // 直线方程参数
        int lineLength = 0;                                // 直线长度
        double lineAngle = 0.;                            // 直线角度
        double opposite = 1.0;                            // 直线的方向是否相反 是:为-1.0,否:1.0
        int imageChs = f.channels();                    // 图像通道数,支持3通道和单通道图像
        cv::Mat singleChImage;                            // 单通道图像
 
        // 有效性判断
        if (f.empty()) return pVec;
        if (pStart == pEnd) return pVec;
 
        // 获取单通道图像
        if (imageChs == 1){
            //f.copyTo(singleChImage);
            singleChImage = f;
        }else if (imageChs == 3){
            cv::cvtColor(f, singleChImage, CV_BGR2GRAY);// 默认的单通道是灰度空间
        }
 
        // 获取直线方向性
        if (pEnd.x < pStart.x) opposite = -1.0;
 
        // 获取直线方程 y = k * x + b, y = b, x = const value.
        if ((pEnd.x - pStart.x) == 0.){
 
            xConst = pStart.x; // x = const value.
            lineAngle = 90.;
            if (pEnd.y < pStart.y) opposite = -1.0;        // 只有这种情况直线方向性考虑Y
        }else{
 
            k = (pEnd.y - pStart.y) / (pEnd.x - pStart.x);
            b = pStart.y - k * pStart.x;
            lineAngle = atan(k) * 180. / CV_PI;
        }
        lineLength = sqrt(pow((pEnd.x - pStart.x), 2.) + pow((pEnd.y - pStart.y), 2.));
 
        // 细分直线,细分步长位gap,获取每一个细分点的坐标
        std::vector<cv::Point2d> gapPVec; gapPVec.clear();
        double Xgap, Ygap;
        for (int g = 0; g <= lineLength; g += gap){
 
            Xgap = pStart.x + (opposite * g * cos(lineAngle * CV_PI / 180.));
            Ygap = (pEnd.x == pStart.x) ? (pStart.y + opposite * g) : (k * Xgap + b);
            gapPVec.push_back(cv::Point2d(Xgap, Ygap));
        }
 
        // 找每个细分点的直线段,直线段长度就是搜索长度范围,由searchLength指定,这边计算出来的lineAngle属于(-90 ~ 90度)
        double halfSearchLength = searchLength / 2.;
        double xLower, xUpper, yLower, yUpper;            // 细分点的直线段在X-Y轴投影的横坐标上限和下限
        double Knew = 0., Bnew = 0., XnewConst = 0.;    // 细分点的直线段的k和b    和x = const直线
        bool newLineIsVecticalLine = false;                // 默认是一般直线,非竖线
        std::vector<cv::Point> lineArrowVec[2];            // 存取用于画结果的直线标
        if (k == 0.){
            newLineIsVecticalLine = true;
        }else{
            if ((pEnd.x == pStart.x)) Knew = 0.;
            else Knew = -1. / k;
        }
        for (int i = 0; i < gapPVec.size(); i++){
 
            if (abs(lineAngle) < 45.){                    // 小于45度的情况
                
                if (newLineIsVecticalLine){ // x = const
 
                    XnewConst = gapPVec[i].x;
                    yLower = gapPVec[i].y - halfSearchLength;
                    yUpper = gapPVec[i].y + halfSearchLength;
                }
                else{                        // b = y - k * x
 
                    Bnew = gapPVec[i].y - Knew * gapPVec[i].x;
                    yLower = gapPVec[i].y - halfSearchLength * cos(abs(lineAngle * CV_PI / 180.));
                    yUpper = gapPVec[i].y + halfSearchLength * cos(abs(lineAngle * CV_PI / 180.));
                }
                // 上边到下边的直线递增查询,下边到上边的直线递减查询
                for (int yy = yLower; yy <= yUpper; yy++){
 
                    int xCur = 0, yCur = 0;
                    if (pStart.x > pEnd.x) yCur = yUpper - yy + yLower;
                    else yCur = yy;
                    xCur = (newLineIsVecticalLine) ? (XnewConst) : (yCur - Bnew) / Knew;
 
                     if (xCur > singleChImage.cols || xCur < 0 || yCur > singleChImage.rows || yCur < 0) continue;
 
                    unsigned char *pdata = singleChImage.ptr<unsigned char>(yCur);
                    if (isJudgeByGreatThan){
 
                        if (pdata[xCur] > threshValue){
 
                            pVec.push_back(cv::Point(xCur, yCur));
                            break;
                        }
                    }
                    else{
 
                        if (pdata[xCur] < threshValue){
 
                            pVec.push_back(cv::Point(xCur, yCur));
                            break;
                        }
                    }
                }
 
                double F_yLower, F_yUpper;
                if (newLineIsVecticalLine){
                    F_yLower = XnewConst;
                    F_yUpper = XnewConst;
                }else{
                    F_yLower = (yLower - Bnew) / Knew;
                    F_yUpper = (yUpper - Bnew) / Knew;
                }
                if (pStart.x < pEnd.x){
                    lineArrowVec[0].push_back(cv::Point(F_yLower, yLower));
                    lineArrowVec[1].push_back(cv::Point(F_yUpper, yUpper));
                }
                else{
                    lineArrowVec[1].push_back(cv::Point(F_yLower, yLower));
                    lineArrowVec[0].push_back(cv::Point(F_yUpper, yUpper));
                }
 
            }else{                        // 大于45度的情况
 
                Bnew = gapPVec[i].y - Knew * gapPVec[i].x;
                xLower = gapPVec[i].x - halfSearchLength * sin(abs(lineAngle * CV_PI / 180.));
                xUpper = gapPVec[i].x + halfSearchLength * sin(abs(lineAngle * CV_PI / 180.));
 
                // 左边到右边的直线递增查询,右边到左边的直线递减查询
                for (int xx = xLower; xx <= xUpper; xx++){
 
                    int xCur = 0, yCur = 0;
                    if (pStart.y > pEnd.y) xCur = xUpper - xx + xLower;
                    else xCur = xx;
                    yCur = Knew * xCur + Bnew;
 
                    if (xCur > singleChImage.cols || xCur < 0 || yCur > singleChImage.rows || yCur < 0) continue;
 
                    unsigned char *pdata = singleChImage.ptr<unsigned char>(yCur);
                    if (isJudgeByGreatThan){
 
                        if (pdata[xCur] > threshValue){
 
                            pVec.push_back(cv::Point(xCur, yCur));
                            break;
                        }
                    }else{
 
                        if (pdata[xCur] < threshValue){
 
                            pVec.push_back(cv::Point(xCur, yCur));
                            break;
                        }
                    }
                }
                double F_xLower = Knew * xLower + Bnew;
                double F_xUpper = Knew * xUpper + Bnew;
                if (pStart.y > pEnd.y){
 
                    lineArrowVec[0].push_back(cv::Point(xUpper, F_xUpper));
                    lineArrowVec[1].push_back(cv::Point(xLower, F_xLower));
                }else{
                    lineArrowVec[1].push_back(cv::Point(xUpper, F_xUpper));
                    lineArrowVec[0].push_back(cv::Point(xLower, F_xLower));
                }
            }
        }// end 'for (int i = 0; i < gapPVec.size(); i++)'
        
        // 画rake点,和搜索方向
        for (int i = 0; i < pVec.size(); i++){
 
            if (imageChs == 1){
 
                cv::circle(f, pVec[i], 3, cv::Scalar(std::rand() % 255), 3);
                drawArrow(f, lineArrowVec[0][i], lineArrowVec[1][i], 25, 30, cv::Scalar(std::rand() % 255), 1);
            }
            if (imageChs == 3){
 
                cv::circle(f, pVec[i], 3, cv::Scalar(std::rand() % 255, std::rand() % 255, std::rand() % 255), 3);
                drawArrow(f, lineArrowVec[0][i], lineArrowVec[1][i], 25, 30, cv::Scalar(std::rand() % 255, std::rand() % 255, std::rand() % 255), 1);
            }
        }
        // 画所有的细分点的搜索方向
        for (int i = 0; i < gapPVec.size(); i++){
 
            if (imageChs == 1){
 
                drawArrow(f, lineArrowVec[0][i], lineArrowVec[1][i], 25, 30, cv::Scalar(std::rand() % 255), 1);
            }
            if (imageChs == 3){
 
                drawArrow(f, lineArrowVec[0][i], lineArrowVec[1][i], 25, 30, cv::Scalar(std::rand() % 255, std::rand() % 255, std::rand() % 255), 1);
            }
        }
 
        return pVec;
}

其中有一个drawArrow函数是用来画箭头的,摘自这里,源码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void drawArrow(cv::Mat& img, cv::Point pStart, cv::Point pEnd, int len, int alpha,cv::Scalar& color, int thickness, int lineType){
 
        cv::Point arrow;
        // 计算 θ 角(最简单的一种情况在下面图示中已经展示,关键在于 atan2 函数,详情见下面)   
        double angle = atan2((double)(pStart.y - pEnd.y), (double)(pStart.x - pEnd.x));
        cv::line(img, pStart, pEnd, color, thickness, lineType);
        // 计算箭角边的另一端的端点位置(上面的还是下面的要看箭头的指向,也就是pStart和pEnd的位置) 
        arrow.x = pEnd.x + len * cos(angle + CV_PI * alpha / 180.);
        arrow.y = pEnd.y + len * sin(angle + CV_PI * alpha / 180.);
        cv::line(img, pEnd, arrow, color, thickness, lineType);
        arrow.x = pEnd.x + len * cos(angle - CV_PI * alpha / 180.);
        arrow.y = pEnd.y + len * sin(angle - CV_PI * alpha / 180.);
        cv::line(img, pEnd, arrow, color, thickness, lineType);
}

本文转自:https://blog.csdn.net/KayChanGEEK/article/details/77247884?utm_source=app

代码语言:javascript
代码运行次数:0
运行
复制
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-12-05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
AVX图像算法优化系列二: 使用AVX2指令集加速查表算法。
  查表算法,无疑也是一种非常常用、有效而且快捷的算法,我们在很多算法的加速过程中都能看到他的影子,在图像处理中,尤其常用,比如我们常见的各种基于直方图的增强,可以说,在photoshop中的调整菜单里80%的算法都是用的查表,因为他最终就是用的曲线调整。
用户1138785
2022/10/28
1.6K0
AVX图像算法优化系列二: 使用AVX2指令集加速查表算法。
SSE图像算法优化
  图像金字塔技术在很多层面上都有着广泛的应用,很多开源的工具也都有对他们的建立写了专门的函数,比如IPP,比如OpenCV等等,这方面的理论文章特别多,我不需要赘述,但是我发现大部多分开源的代码的实现都不是严格意义上的金字塔,而是做了一定的变通,这种变通常常为了快捷的实现类似的效果,虽然这种变通不太会影响金字塔的效果,但是我这里希望从严格意义上对该算法进行优化,比如简要贴一下下面的某个高斯金字塔的代码:
用户1138785
2019/05/24
1.1K0
SSE图像算法优化系列2-高斯滤波
或许大多数人对于高斯滤波的印象都停留在使用一个高斯在图像滑动然后计算结果。这的确没错,但从速度上考虑这种模式是难以优化的。也导致在极大分辨率图像上进行高斯滤波是压根不可行的。幸运的是,高斯滤波实际上还有另外一种表达方式,那就是递归表达。这最早见于《Recursive implementation of the Gaussian filter》论文中:
BBuf
2019/12/04
1.2K0
SSE图像算法优化系列2-高斯滤波
【AI PC端算法优化】一,一步步优化RGB转灰度图算法
公众号输入 「高性能计算」 关键词获取刘文志大佬的《并行编程方法与优化实践》电子书以及我整理的SSE指令集PDF。
BBuf
2020/04/15
1.7K0
【AI PC端算法优化】一,一步步优化RGB转灰度图算法
【工程应用五】 opencv中linemod模板匹配算法诸多疑惑和自我解读。
        研究这个前前后后也有快两三个月了,因为之前也一直在弄模板匹配方面的东西,所以偶尔还是有不少朋友咨询或者问你有没有研究过linemod这个算法啊,那个效率啥的还不错啊,有段时间一直不以为然,觉得我现在用的那个匹配因该很不错的,没必要深究了。后来呢,还是忍不住手痒,把论文打出来看了看,又找了点资料研究了下,结果没想到一弄又是两个月过去了,中间也折腾了很久,浪费了不少时间。总算还是有点收获,稍微整理下做个交流。
用户1138785
2022/05/09
1.6K0
【工程应用五】 opencv中linemod模板匹配算法诸多疑惑和自我解读。
【短道速滑】OpenCV中cvResize函数使用双线性插值缩小图像长宽大小一半时速度飞快(比最近邻还快)之异象解析和自我实现。
作者网名:laviewpbt 是图像处理,算法实现与加速优化方面的大神!其开发的imageshop软件大小只有1MB,却实现了非常丰富与复杂的各种图像处理功能, 邮箱地址为:Email: laviewpbt@sina.com 博客地址:https://www.cnblogs.com/Imageshop/
OpenCV学堂
2020/03/31
9380
SSE图像算法优化系列二:高斯模糊算法的全面优化过程分享(一)。
根据文章内容总结的摘要
用户1138785
2018/01/03
2.2K0
SSE图像算法优化系列二:高斯模糊算法的全面优化过程分享(一)。
[强基固本-视频压缩]第十二章:向量指令 第一部分
向量计算是在执行单个处理器指令时,对多个数据块同时执行相同类型的多个操作。这一原理也被称为 SIMD(单指令多数据)。这个名字源于与向量代数的明显相似性:向量之间的操作具有单一符号表示,但涉及对向量各分量执行多个算术操作。
用户1324186
2024/03/20
2440
[强基固本-视频压缩]第十二章:向量指令 第一部分
解析opencv中Box Filter的实现并提出进一步加速的方案(源码共享)。
用户1138785
2018/01/03
1.8K0
解析opencv中Box Filter的实现并提出进一步加速的方案(源码共享)。
深度优化局部拉普拉斯金字塔滤波器
基于局部拉普拉斯金字塔的Edge-aware滤波器是在2011年由Adobe 公司的研究员Sylvain Paris(大神级人物,写了很多文章)提出的,我在4年前曾经参考有关代码实现过这个算法,但是速度也是非常慢的,所以当时也没有继续做深入的研究,前段时间做另外一个算法时仔细的研究了下高斯和拉普拉斯金子塔的优化,因此又抽时间仔细的分析了算法的论文和代码,由于论文的理论部分还有一些我没有想清楚,因此在这里我只对研读过程中涉及的代码方面的优化做个解读。
用户1138785
2019/05/24
1.3K0
[快速阅读六] 统计内存数据中二进制1的个数(SSE指令集优化版).
  关于这个问题,网络上讨论的很多,可以找到大量的资料,我觉得就就是下面这一篇讲的最好,也非常的全面:
用户1138785
2024/05/31
1610
[快速阅读六] 统计内存数据中二进制1的个数(SSE指令集优化版).
【算法随记七】巧用SIMD指令实现急速的字节流按位反转算法。
  字节按位反转算法,在有些算法加密或者一些特殊的场合有着较为重要的应用,其速度也是一个非常关键的应用,比如一个byte变量a = 3,其二进制表示为00000011,进行按位反转后的结果即为11000000,即十进制的192。还有一种常用的应用是int型变量按位反转,其基本的原理和字节反转类似,本文仅以字节反转为例来比较这个算法的实现。
用户1138785
2020/01/02
1.3K0
Opencv中goodFeaturesToTrack函数(Harris角点、Shi-Tomasi角点检测)算子速度的进一步优化(1920*1080测试图11ms处理完成)。
  搜索到某个效果很好的视频去燥的算法,感觉效果比较牛逼,就是速度比较慢,如果能做到实时,那还是很有实用价值的。于是盲目的选择了这个课题,遇到的第一个函数就是角点检测,大概六七年用过C#实现过Harris角点以及SUSAN角点。因此相关的理论还是有所了解的,不过那个时候重点在于实现,对于效率没有过多的考虑。
用户1138785
2023/11/02
6150
Opencv中goodFeaturesToTrack函数(Harris角点、Shi-Tomasi角点检测)算子速度的进一步优化(1920*1080测试图11ms处理完成)。
深度优化局部拉普拉斯金字塔滤波器。
基于局部拉普拉斯金字塔的Edge-aware滤波器是在2011年由Adobe 公司的研究员Sylvain Paris(大神级人物,写了很多文章)提出的,我在4年前曾经参考有关代码实现过这个算法,但是速度也是非常慢的,所以当时也没有继续做深入的研究,前段时间做另外一个算法时仔细的研究了下高斯和拉普拉斯金子塔的优化,因此又抽时间仔细的分析了算法的论文和代码,由于论文的理论部分还有一些我没有想清楚,因此在这里我只对研读过程中涉及的代码方面的优化做个解读。
OpenCV学堂
2019/03/07
2.5K0
【AI PC端算法优化】四,一步步将Sobel边缘检测加速22倍
继续优化技术的探索,今天以一个的Sobel算子进行边缘检测的算法为例来看看如何使用SSE指令集对其进行优化。
BBuf
2020/04/20
1.5K0
【AI PC端算法优化】四,一步步将Sobel边缘检测加速22倍
SSE图像算法优化系列四:图像转置的SSE优化(支持8位、24位、32位),提速4-6倍
本文介绍了如何利用SSE/AVX指令集进行CPU并行加速,以解决图像转置中存在的内存访问瓶颈问题。首先介绍了图像转置的算法和实现过程,然后通过具体示例展示了如何使用SSE/AVX指令集进行CPU并行加速,最后给出了针对不同CPU架构的优化策略。
用户1138785
2018/01/03
2.1K0
Intel 内部指令 — AVX和AVX2学习笔记[通俗易懂]
将饱和度考虑在内的函数将结果钳制到可以存储的最小/最大值。没有饱和的函数在饱和发生时忽略内存问题。
全栈程序员站长
2022/09/02
3.3K1
Intel 内部指令 — AVX和AVX2学习笔记[通俗易懂]
【AI PC端算法优化】六,优化一个简单的肤色检测算法
继续学习优化知识,这一节将以一个简单的肤色检测算法为例谈谈当一个算法中有比较运算符时,我们该如何向量化并进行加速,简单来说就是如何将比较运算语句写成SSE指令。
BBuf
2020/04/26
8730
【AI PC端算法优化】六,优化一个简单的肤色检测算法
【工程应用六】 继续聊一聊高效率的模板匹配算法(分水岭助威+蒙版提速)。
       总是写很长的复杂的文章,目前发现真的有点无法静心去弄了,感觉写代码的动力要比写文章强大的多,所以,往后的文章还是写的剪短一点吧。
用户1138785
2022/05/18
1.6K0
【工程应用六】 继续聊一聊高效率的模板匹配算法(分水岭助威+蒙版提速)。
【AI PC端算法优化】二,一步步优化自然饱和度算法
今天要介绍的自然饱和度算法是一个开源图像处理软件PhotoDemon(地址:https://github.com/tannerhelland/PhotoDemon)上的,原版是C#的,代码如下:
BBuf
2020/04/15
7340
【AI PC端算法优化】二,一步步优化自然饱和度算法
推荐阅读
AVX图像算法优化系列二: 使用AVX2指令集加速查表算法。
1.6K0
SSE图像算法优化
1.1K0
SSE图像算法优化系列2-高斯滤波
1.2K0
【AI PC端算法优化】一,一步步优化RGB转灰度图算法
1.7K0
【工程应用五】 opencv中linemod模板匹配算法诸多疑惑和自我解读。
1.6K0
【短道速滑】OpenCV中cvResize函数使用双线性插值缩小图像长宽大小一半时速度飞快(比最近邻还快)之异象解析和自我实现。
9380
SSE图像算法优化系列二:高斯模糊算法的全面优化过程分享(一)。
2.2K0
[强基固本-视频压缩]第十二章:向量指令 第一部分
2440
解析opencv中Box Filter的实现并提出进一步加速的方案(源码共享)。
1.8K0
深度优化局部拉普拉斯金字塔滤波器
1.3K0
[快速阅读六] 统计内存数据中二进制1的个数(SSE指令集优化版).
1610
【算法随记七】巧用SIMD指令实现急速的字节流按位反转算法。
1.3K0
Opencv中goodFeaturesToTrack函数(Harris角点、Shi-Tomasi角点检测)算子速度的进一步优化(1920*1080测试图11ms处理完成)。
6150
深度优化局部拉普拉斯金字塔滤波器。
2.5K0
【AI PC端算法优化】四,一步步将Sobel边缘检测加速22倍
1.5K0
SSE图像算法优化系列四:图像转置的SSE优化(支持8位、24位、32位),提速4-6倍
2.1K0
Intel 内部指令 — AVX和AVX2学习笔记[通俗易懂]
3.3K1
【AI PC端算法优化】六,优化一个简单的肤色检测算法
8730
【工程应用六】 继续聊一聊高效率的模板匹配算法(分水岭助威+蒙版提速)。
1.6K0
【AI PC端算法优化】二,一步步优化自然饱和度算法
7340
相关推荐
AVX图像算法优化系列二: 使用AVX2指令集加速查表算法。
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验