多线程处理图片

使用了 thread 线程库

// pthreadDemo.cpp : 定义控制台应用程序的入口点。
//

#include <stdio.h>
#include <pthread.h>
#include <assert.h>
#include <string>
#include <opencv2/opencv.hpp>
using namespace std;
#define THREAD_NUMS 3

/*paramThread用于传递线程需要的参数值*/
struct paramThread
{
    int w;
    int h;
    uchar * data;
};

/********************************************************
*	@brief       : 多线程处理函数
*	@param  args : 多线程传入的参数
*	@return      : void
********************************************************/
void * threadProcess(void* args) {

    pthread_t myid = pthread_self();
    paramThread *para = (paramThread *)args;
    int w = para->w;
    int h = para->h;
    cv::Mat image(h,w,CV_8UC3,(uchar *)para->data);
    //cv::cvtColor(image, image, cv::COLOR_BGR2RGB);
    cv::blur(image, image,cv::Size(7,7), cv::Point(-1, -1), cv::BORDER_REPLICATE);
    //printf("thread id = %d, w=%d, h=%d\n", myid, w,h);
    //cv::imshow("image", image); cv::waitKey(2000);
    pthread_exit(NULL);
    return NULL;
}

/********************************************************
*	@brief       : 实现图像分割,
*	@param  num  :  分割个数
*	@param  type : 0:垂直分割(推荐),1:水平分割(不推荐)
*	@return      : vector<cv::Mat>
*   PS:使用水平分割时(type=1),处理完后必须调用catImage进行拼接,
*   使用垂直分割时(type=0),可以不进行catImage,因为是对原图进行操作的
********************************************************/
vector<cv::Mat> splitImage(cv::Mat image, int num,int type) {
    int rows = image.rows;
    int cols = image.cols;
    vector<cv::Mat> v;
    if (type == 0) {//垂直分割
        for (size_t i = 0; i < num; i++) {
            int star = rows / num*i;
            int end = rows / num*(i + 1);
            if (i == num - 1) {
                end = rows;
            }
            //cv::Mat b = image.rowRange(star, end);
            v.push_back(image.rowRange(star, end));
        }
    }
    else if (type == 1) {//水平分割
        for (size_t i = 0; i < num; i++){
            int star = cols / num*i;
            int end = cols / num*(i + 1);
            if (i == num - 1) {
                end = cols;
            }
            //cv::Mat b = image.colRange(star, end);
            /*解决水平分割的Bug:必须clone()*/
            v.push_back(image.colRange(star, end).clone());
        }
    }
    return  v;
}

/********************************************************
*	@brief       : 实现图像拼接,
*	@param  v    :  
*	@param  type : 0:垂直拼接,1:水平拼接
*	@return      : Mat
********************************************************/
cv::Mat catImage(vector<cv::Mat> v, int type) {
    cv::Mat dest= v.at(0);
    for (size_t i = 1; i < v.size(); i++)
    {
        if (type == 0)//垂直拼接
        {
            cv::vconcat(dest, v.at(i), dest);
        }
        else if (type == 1)//水平拼接
        {
            cv::hconcat(dest, v.at(i), dest);
        }
    }
    return dest;
}

int main() {
    string path = "/home/mayang/Firefox_wallpaper.png";
    cv::Mat src = cv::imread(path);
    printf("image size =  w=%d, h=%d\n", src.cols, src.rows);

    cv::Mat image1 = src.clone();
    cv::Mat image2 = src.clone();
    cv::imshow("src", src); cv::waitKey(30);

    double T0 = static_cast<double>(cv::getTickCount());
    /*不使用多线程图像处理*/
    cv::blur(image1, image1, cv::Size(7, 7));
    double T1 = static_cast<double>(cv::getTickCount());

    /*使用多线程图像处理*/
    int type = 0;
    vector<cv::Mat> v = splitImage(image2, THREAD_NUMS, type);
    paramThread args[THREAD_NUMS];
    pthread_t pt[THREAD_NUMS];	//创建THREAD_NUMS个子线程
    for (size_t i = 0; i < THREAD_NUMS; i++)
    {
        args[i].h = v.at(i).rows;
        args[i].w = v.at(i).cols;
        args[i].data = v.at(i).data;
        pthread_create(&pt[i], NULL, &threadProcess, (void *)(&args[i]));
    }
    /*等待全部子线程处理完毕*/
    for (size_t i = 0; i < THREAD_NUMS; i++)
    {
        pthread_join(pt[i], NULL);
    }
    cv::Mat dest = catImage(v, type);
    double T2 = static_cast<double>(cv::getTickCount());
    printf("       run times = %3.3fms\n", (T1 - T0)*1000 / cv::getTickFrequency());
    printf("Thread run times = %3.3fms\n,", (T2 - T1)*1000 / cv::getTickFrequency());

    cv::imshow("dest", dest); cv::waitKey(30);
    cv::imshow("image2", image2); cv::waitKey(30);


    cv::waitKey(0);
    return 0;
}

CmakeLists 配置

cmake_minimum_required(VERSION 3.14)
project(untitled)


set(CMAKE_CXX_STANDARD 14)

find_package(OpenCV REQUIRED)

set(SOURCE_FILES main.cpp)
add_executable(untitled ${SOURCE_FILES})

include_directories(${OpenCV_INCLUDE_DIRS})
target_link_libraries(untitled ${OpenCV_LIBS} boost_thread -pthread)

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
压缩包中包含的具体内容: 对给定数据中的6个不同场景图像,进行全景图拼接操作,具体要求如下: (1) 寻找关键点,获取关键点的位置和尺度信息(DoG检测子已由KeypointDetect文件夹中的detect_features_DoG.m文件实现;请参照该算子,自行编写程序实现Harris-Laplacian检测子)。 (2) 在每一幅图像中,对每个关键点提取待拼接图像的SIFT描述子(编辑SIFTDescriptor.m文件实现该操作,运行EvaluateSIFTDescriptor.m文件检查实现结果)。 (3) 比较来自两幅不同图像的SIFT描述子,寻找匹配关键点(编辑SIFTSimpleMatcher.m文件计算两幅图像SIFT描述子间的Euclidean距离,实现该操作,运行EvaluateSIFTMatcher.m文件检查实现结果)。 (4) 基于图像中的匹配关键点,对两幅图像进行配准。请分别采用最小二乘方法(编辑ComputeAffineMatrix.m文件实现该操作,运行EvaluateAffineMatrix.m文件检查实现结果)和RANSAC方法估计两幅图像间的变换矩阵(编辑RANSACFit.m 文件中的ComputeError()函数实现该操作,运行TransformationTester.m文件检查实现结果)。 (5) 基于变换矩阵,对其中一幅图像进行变换处理,将其与另一幅图像进行拼接。 (6) 对同一场景的多幅图像进行上述操作,实现场景的全景图拼接(编辑MultipleStitch.m文件中的makeTransformToReferenceFrame函数实现该操作)。可以运行StitchTester.m查看拼接结果。 (7) 请比较DoG检测子和Harris-Laplacian检测子的实验结果。图像拼接的效果对实验数据中的几个场景效果不同,请分析原因。 已经实现这些功能,并且编译运行均不报错!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值