c++多线程和opencv图像显示问题,急,有偿

想用c++的thread和opencv打开多个窗口实现排序算法的可视化,
可是子窗口不显示排序过程,过一会直接显示排序结果。
刚开始运行时

img


最后能显示出来结果,但是看不见过程

img


下面是代码块
有知道怎么解决的吗,可以加v细说,也可直接评论。v是j15349790396

#include <iostream>
#include <vector>
#include <thread>
#include <chrono>
#include <algorithm>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

vector<int> generateRandomArray(int size) {
    vector<int> arr(size);
    for (int i = 0; i < size; i++) {
        arr[i] = rand() % 100;
    }
    return arr;
}

void bubbleSort(vector<int>& arr, Mat& img) {
    int n = arr.size();
    for (int i = 0; i < n - 1; i++) {
        bool swapped = false;
        for (int j = 0; j < n - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                swap(arr[j], arr[j + 1]);
                swapped = true;
            }
        }
        if (swapped) {
            img.setTo(Scalar(255, 255, 255)); // clear the image
            for (int k = 0; k < n; k++) {
                line(img, Point(k * 5, 500), Point(k * 5, 500 - arr[k] * 5), Scalar(0, 0, 0), 2);
            }
            imshow("Bubble Sort", img);
            waitKey(50); // wait for 50 milliseconds
        }
    }
}

void quickSort(vector<int>& arr, int low, int high, Mat& img) {
    if (low < high) {
        int pivot = arr[high];
        int i = low - 1;
        for (int j = low; j < high; j++) {
            if (arr[j] < pivot) {
                i++;
                swap(arr[i], arr[j]);
                
            }
        }
        swap(arr[i + 1], arr[high]);
        
        img.setTo(Scalar(255, 255, 255)); // clear the image
        for (int k = 0; k < arr.size(); k++) {
            line(img, Point(k * 5, 500), Point(k * 5, 500 - arr[k] * 5), Scalar(0, 0, 0), 2);
        }
        imshow("Quick Sort", img);
        waitKey(50); // wait for 50 milliseconds
        int pivotIndex = i + 1;
        //quickSort(arr, low, pivotIndex - 1, img);
        // quickSort(arr, pivotIndex + 1, high, img);
        
        thread leftThread(quickSort, ref(arr), low, pivotIndex - 1, ref(img));
        thread rightThread(quickSort, ref(arr), pivotIndex + 1, high, ref(img));
        leftThread.join();
        rightThread.join();
    }
}

void merge(vector<int>& arr, int left, int middle, int right, Mat& img) {
    int i = left, j = middle + 1, k = 0;
    vector<int> temp(right - left + 1);
    while (i <= middle && j <= right) {
        if (arr[i] < arr[j]) {
            temp[k++] = arr[i++];
        }
        else {
            temp[k++] = arr[j++];
        }
    }
    while (i <= middle) {
        temp[k++] = arr[i++];
    }
    while (j <= right) {
        temp[k++] = arr[j++];
    }
    for (i = left, k = 0; i <= right; i++, k++) {
        arr[i] = temp[k];
    }
    img.setTo(Scalar(255, 255, 255)); // clear the image
    for (int k = 0; k < arr.size(); k++) {
        line(img, Point(k * 5, 500), Point(k * 5, 500 - arr[k] * 5), Scalar(0, 0, 0), 2);
    }
    imshow("Merge Sort", img);
    waitKey(50); // wait for 50 milliseconds
}

void mergeSort(vector<int>& arr, int left, int right, Mat& img) {
    if (left < right) {
        int middle = (left + right) / 2;
        mergeSort(arr, left, middle, img);
        mergeSort(arr, middle + 1, right, img);
        merge(arr, left, middle, right, img);
    }
}

int main() {
    srand(time(NULL));
    int size = 100;
    vector<int> arr = generateRandomArray(size);
    Mat bubbleSortImg = Mat::zeros(640, 480, CV_8UC3);
    Mat quickSortImg = Mat::zeros(640, 480, CV_8UC3);
    Mat mergeSortImg = Mat::zeros(640, 480, CV_8UC3);
    namedWindow("Bubble Sort", WINDOW_NORMAL);
    namedWindow("Quick Sort", WINDOW_NORMAL);
    namedWindow("Merge Sort", WINDOW_NORMAL);
    resizeWindow("Bubble Sort", 640, 480);
    resizeWindow("Quick Sort", 640, 480);
    resizeWindow("Merge Sort", 640, 480);
    moveWindow("Bubble Sort", 0, 0);
    moveWindow("Quick Sort", 640, 0);
    moveWindow("Merge Sort", 1280, 0);
    bubbleSortImg.setTo(Scalar(255, 255, 255));
    quickSortImg.setTo(Scalar(255, 255, 255));
    mergeSortImg.setTo(Scalar(255, 255, 255));
    imshow("Bubble Sort", bubbleSortImg);
    imshow("Quick Sort", quickSortImg);
    imshow("Merge Sort", mergeSortImg);
    thread bubbleSortThread(bubbleSort, ref(arr), ref(bubbleSortImg));
    thread quickSortThread(quickSort, ref(arr), 0, size - 1, ref(quickSortImg));
    thread mergeSortThread(mergeSort, ref(arr), 0, size - 1, ref(mergeSortImg));
    bubbleSortThread.join();
    quickSortThread.join();
    mergeSortThread.join();
    waitKey(0);
    return 0;
}

好像是opencv的imshow不能在子线程运行的,需要加锁然后写个队列显示,像你这个多个窗口的,我估计还要用map封装一层队列,分别进各自窗口的队列

#include <iostream>
#include <vector>
#include <thread>
#include <chrono>
#include <algorithm>
#include <opencv2/opencv.hpp>
#include<map>
#include <queue>

using namespace std;
using namespace cv;

std::map<string ,std::queue<cv::Mat>> imshowMat;// <窗口名,队列>
mutex g_mutex;//进程锁
int  key = 0;

vector<int> generateRandomArray(int size) {
    vector<int> arr(size);
    for (int i = 0; i < size; i++) {
        arr[i] = rand() % 100;
    }
    return arr;
}

void bubbleSort(vector<int>& arr, Mat& img) {
    int n = arr.size();
    for (int i = 0; i < n - 1; i++) {
        bool swapped = false;
        for (int j = 0; j < n - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                swap(arr[j], arr[j + 1]);
                swapped = true;
            }
        }
        if (swapped) {
            img.setTo(Scalar(255, 255, 255)); // clear the image
            for (int k = 0; k < n; k++) {
                line(img, Point(k * 5, 500), Point(k * 5, 500 - arr[k] * 5), Scalar(0, 0, 0), 2);
            }
            g_mutex.lock();//修改公共资源,用进程锁锁定
            if (imshowMat.count("Bubble Sort") < 1)
            {
                queue<Mat> tempQueue;
                tempQueue.push(img.clone());
                imshowMat.emplace(pair<string, std::queue<Mat>>("Bubble Sort", tempQueue));

            }
            else
             imshowMat["Bubble Sort"].push(img.clone());
            g_mutex.unlock();  //释放锁

            //imshow("Bubble Sort", img);
            waitKey(50); // wait for 50 milliseconds
        }
    }
}

void quickSort(vector<int>& arr, int low, int high, Mat& img) {
    if (low < high) {
        int pivot = arr[high];
        int i = low - 1;
        for (int j = low; j < high; j++) {
            if (arr[j] < pivot) {
                i++;
                swap(arr[i], arr[j]);

            }
        }
        swap(arr[i + 1], arr[high]);

        img.setTo(Scalar(255, 255, 255)); // clear the image
        for (int k = 0; k < arr.size(); k++) {
            line(img, Point(k * 5, 500), Point(k * 5, 500 - arr[k] * 5), Scalar(0, 0, 0), 2);
        }
        g_mutex.lock();//修改公共资源,用进程锁锁定
        if (imshowMat.count("Quick Sort") < 1)
        {
            queue<Mat> tempQueue;
            tempQueue.push(img.clone());
            imshowMat.emplace(pair<string, std::queue<Mat>>("Quick Sort", tempQueue));

        }
        else
            imshowMat["Quick Sort"].push(img.clone());
        g_mutex.unlock();  //释放锁

        //imshow("Quick Sort", img);
        waitKey(50); // wait for 50 milliseconds
        int pivotIndex = i + 1;
        //quickSort(arr, low, pivotIndex - 1, img);
        // quickSort(arr, pivotIndex + 1, high, img);

        thread leftThread(quickSort, ref(arr), low, pivotIndex - 1, ref(img));
        thread rightThread(quickSort, ref(arr), pivotIndex + 1, high, ref(img));
        leftThread.join();
        rightThread.join();
    }
}

void merge(vector<int>& arr, int left, int middle, int right, Mat& img) {
    int i = left, j = middle + 1, k = 0;
    vector<int> temp(right - left + 1);
    while (i <= middle && j <= right) {
        if (arr[i] < arr[j]) {
            temp[k++] = arr[i++];
        }
        else {
            temp[k++] = arr[j++];
        }
    }
    while (i <= middle) {
        temp[k++] = arr[i++];
    }
    while (j <= right) {
        temp[k++] = arr[j++];
    }
    for (i = left, k = 0; i <= right; i++, k++) {
        arr[i] = temp[k];
    }
    img.setTo(Scalar(255, 255, 255)); // clear the image
    for (int k = 0; k < arr.size(); k++) {
        line(img, Point(k * 5, 500), Point(k * 5, 500 - arr[k] * 5), Scalar(0, 0, 0), 2);
    }

    g_mutex.lock();//修改公共资源,用进程锁锁定

    if (imshowMat.count("Merge Sort") < 1)
    {
        queue<Mat> tempQueue;
        tempQueue.push(img.clone());
        imshowMat.emplace(pair<string, std::queue<Mat>>("Merge Sort", tempQueue));

    }
    else
    imshowMat["Merge Sort"].push(img.clone());
    g_mutex.unlock();  //释放锁

    //imshow("Merge Sort", img);
    waitKey(50); // wait for 50 milliseconds
}

void mergeSort(vector<int>& arr, int left, int right, Mat& img) {
    if (left < right) {
        int middle = (left + right) / 2;
        mergeSort(arr, left, middle, img);
        mergeSort(arr, middle + 1, right, img);
        merge(arr, left, middle, right, img);
    }
}

void showMat() {

    Mat frame;
    while (key != 27) //q退出
    {
        
        if (!imshowMat["Bubble Sort"].empty())//队列里面有帧
        {
            g_mutex.lock();
            frame = imshowMat["Bubble Sort"].front();
            imshowMat["Bubble Sort"].pop();
            g_mutex.unlock();
            cv::imshow("Bubble Sort", frame);
        }
        if (!imshowMat["Quick Sort"].empty())//队列里面有帧
        {
            g_mutex.lock();
            frame = imshowMat["Quick Sort"].front();
            imshowMat["Quick Sort"].pop();
            g_mutex.unlock();

            cv::imshow("Quick Sort", frame);
        }
        if (!imshowMat["Merge Sort"].empty())//队列里面有帧
        {
            g_mutex.lock();
            frame = imshowMat["Merge Sort"].front();
            imshowMat["Merge Sort"].pop();
            g_mutex.unlock();

            cv::imshow("Merge Sort", frame);
        }

        cv::waitKey(50);
    }


}

int main() {
    srand(time(NULL));
    int size = 100;
    vector<int> arr = generateRandomArray(size);
    Mat bubbleSortImg = Mat::zeros(640, 480, CV_8UC3);
    Mat quickSortImg = Mat::zeros(640, 480, CV_8UC3);
    Mat mergeSortImg = Mat::zeros(640, 480, CV_8UC3);


    namedWindow("Bubble Sort", WINDOW_NORMAL);
    namedWindow("Quick Sort", WINDOW_NORMAL);
    namedWindow("Merge Sort", WINDOW_NORMAL);
    resizeWindow("Bubble Sort", 640, 480);
    resizeWindow("Quick Sort", 640, 480);
    resizeWindow("Merge Sort", 640, 480);
    moveWindow("Bubble Sort", 0, 0);
    moveWindow("Quick Sort", 640, 0);
    moveWindow("Merge Sort", 1280, 0);
    bubbleSortImg.setTo(Scalar(255, 255, 255));
    quickSortImg.setTo(Scalar(255, 255, 255));
    mergeSortImg.setTo(Scalar(255, 255, 255));
    //imshow("Bubble Sort", bubbleSortImg);
    //imshow("Quick Sort", quickSortImg);
    ////imshow("Merge Sort", mergeSortImg);

    thread show_Mat(showMat);
    show_Mat.detach();
    //show_Mat.detach();
    thread bubbleSortThread(bubbleSort, ref(arr), ref(bubbleSortImg));
    thread quickSortThread(quickSort, ref(arr), 0, size - 1, ref(quickSortImg));
    thread mergeSortThread(mergeSort, ref(arr), 0, size - 1, ref(mergeSortImg));


    bubbleSortThread.detach();
    quickSortThread.detach();
    mergeSortThread.detach();
    waitKey(0);
    key = 27;//退出
    return 0;
}


记住这个原则:不要在子线程中进行界面显示相关操作

opencv多线程同时显示图片

可以借鉴下
https://blog.csdn.net/zhuoyueljl/article/details/87909209

ipconfig6.7.4.8:8476m/u/n/n(u(m4/6/7/8/9m)u)n/n/u/mTCPIP代:理=服=务:器4.6.7.8:4678www.4.6.7.8:4678.com.cn.4.6.7.8:4678.com

该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
您好!根据您提供的代码,我看到您使用了OpenCV的imshow函数在多线程中展示排序算法的可视化效果。然而,OpenCV的GUI函数通常只能在主线程中使用,因此在子线程中使用imshow函数可能无法正常工作。

为了解决这个问题,您可以在主线程中创建Mat对象,并将其传递给子线程。在子线程中,对Mat对象进行操作,然后将Mat对象传回主线程。在主线程中使用imshow函数显示Mat对象。这样就可以在主线程中使用OpenCV的GUI函数,同时保持多线程的效率。

具体实现方式如下:

1、 在主线程中创建Mat对象,并将其传递给子线程:

Mat bubbleSortImg = Mat::zeros(640, 480, CV_8UC3);
Mat quickSortImg = Mat::zeros(640, 480, CV_8UC3);
Mat mergeSortImg = Mat::zeros(640, 480, CV_8UC3);

2、 在子线程中对Mat对象进行操作:

void bubbleSort(vector<int>& arr, Mat& img) {
    // ...
    img.setTo(Scalar(255, 255, 255)); // clear the image
    for (int k = 0; k < n; k++) {
        line(img, Point(k * 5, 500), Point(k * 5, 500 - arr[k] * 5), Scalar(0, 0, 0), 2);
    }
    // ...
}

void quickSort(vector<int>& arr, int low, int high, Mat& img) {
    // ...
    img.setTo(Scalar(255, 255, 255)); // clear the image
    for (int k = 0; k < arr.size(); k++) {
        line(img, Point(k * 5, 500), Point(k * 5, 500 - arr[k] * 5), Scalar(0, 0, 0), 2);
    }
    // ...
}

void merge(vector<int>& arr, int left, int middle, int right, Mat& img) {
    // ...
    img.setTo(Scalar(255, 255, 255)); // clear the image
    for (int k = 0; k < arr.size(); k++) {
        line(img, Point(k * 5, 500), Point(k * 5, 500 - arr[k] * 5), Scalar(0, 0, 0), 2);
    }
    // ...
}

3、 将Mat对象传回主线程:

void bubbleSort(vector<int>& arr, Mat& img, promise<Mat>& prom) {
    // ...
    prom.set_value(img);
    // ...
}

void quickSort(vector<int>& arr, int low, int high, Mat& img, promise<Mat>& prom) {
    // ...
    prom.set_value(img);
    // ...
}

void mergeSort(vector<int>& arr, int left, int right, Mat& img, promise<Mat>& prom) {
    // ...
    prom.set_value(img);
    // ...
}

4、 在主线程中等待子线程完成,并使用imshow函数显示Mat对象:

thread bubbleSortThread(bubbleSort, ref(arr), ref(bubbleSortImg), move(bubbleSortProm));
thread quickSortThread(quickSort, ref(arr), 0, size - 1, ref(quickSortImg), move(quickSortProm));
thread mergeSortThread(mergeSort, ref(arr), 0, size - 1, ref(mergeSortImg), move(mergeSortProm));

bubbleSortThread.join();
bubbleSortImg = bubbleSortProm.get_future().get();
imshow("Bubble Sort", bubbleSortImg);

quickSortThread.join();
quickSortImg = quickSortProm.get_future().get();
imshow("Quick Sort", quickSortImg);

mergeSortThread.join();
mergeSortImg = mergeSortProm.get_future().get();
imshow("Merge Sort", mergeSortImg);

waitKey(0);

希望这些解决方案能够帮助您解决问题!


如果以上回答对您有所帮助,点击一下采纳该答案~谢谢

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
对于多线程和OpenCV图像显示的问题,你需要在主线程中创建窗口,并分别为每个排序算法创建一个窗口。然后在每个算法的子线程中使用imshow和waitKey从子线程中更新窗口。至于排序的可视化,你需要在每次排序后,使用Mat的setTo清除上一轮排序的图像,并使用line在Mat上绘制当前排序的图像。

对于子窗口不显示排序过程的问题,你可以尝试使用waitKey函数增加每次更新窗口的间隔时间,使程序有更充足的时间去更新窗口。

下面是修改过的代码:

#include <iostream>
#include <vector>
#include <thread>
#include <chrono>
#include <algorithm>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

vector<int> generateRandomArray(int size) {
    vector<int> arr(size);
    for (int i = 0; i < size; i++) {
        arr[i] = rand() % 100;
    }
    return arr;
}

void bubbleSort(vector<int>& arr, Mat& img, int delay) {
    int n = arr.size();
    for (int i = 0; i < n - 1; i++) {
        bool swapped = false;
        for (int j = 0; j < n - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                swap(arr[j], arr[j + 1]);
                swapped = true;
            }
        }
        if (swapped) {
            img.setTo(Scalar(255, 255, 255)); // clear the image
            for (int k = 0; k < n; k++) {
                line(img, Point(k * 5, 500), Point(k * 5, 500 - arr[k] * 5), Scalar(0, 0, 0), 2);
            }
            imshow("Bubble Sort", img);
            waitKey(delay); // wait for delay milliseconds
        }
    }
}

void quickSort(vector<int>& arr, int low, int high, Mat& img, int delay) {
    if (low < high) {
        int pivot = arr[high];
        int i = low - 1;
        for (int j = low; j < high; j++) {
            if (arr[j] < pivot) {
                i++;
                swap(arr[i], arr[j]);
            }
        }
        swap(arr[i + 1], arr[high]);
        
        img.setTo(Scalar(255, 255, 255)); // clear the image
        for (int k = 0; k < arr.size(); k++) {
            line(img, Point(k * 5, 500), Point(k * 5, 500 - arr[k] * 5), Scalar(0, 0, 0), 2);
        }
        imshow("Quick Sort", img);
        waitKey(delay); // wait for delay milliseconds
        int pivotIndex = i + 1;
        thread leftThread(quickSort, ref(arr), low, pivotIndex - 1, ref(img), delay);
        thread rightThread(quickSort, ref(arr), pivotIndex + 1, high, ref(img), delay);
        leftThread.join();
        rightThread.join();
    }
}

void merge(vector<int>& arr, int left, int middle, int right, Mat& img) {
    int i = left, j = middle + 1, k = 0;
    vector<int> temp(right - left + 1);
    while (i <= middle && j <= right) {
        if (arr[i] < arr[j]) {
            temp[k++] = arr[i++];
        }
        else {
            temp[k++] = arr[j++];
        }
    }
    while (i <= middle) {
        temp[k++] = arr[i++];
    }
    while (j <= right) {
        temp[k++] = arr[j++];
    }
    for (i = left, k = 0; i <= right; i++, k++) {
        arr[i] = temp[k];
    }
    img.setTo(Scalar(255, 255, 255)); // clear the image
    for (int k = 0; k < arr.size(); k++) {
        line(img, Point(k * 5, 500), Point(k * 5, 500 - arr[k] * 5), Scalar(0, 0, 0), 2);
    }
    imshow("Merge Sort", img);
    waitKey(50); // wait for 50 milliseconds
}

void mergeSort(vector<int>& arr, int left, int right, Mat& img, int delay) {
    if (left < right) {
        int middle = (left + right) / 2;
        mergeSort(arr, left, middle, img, delay);
        mergeSort(arr, middle + 1, right, img, delay);
        merge(arr, left, middle, right, img);
    }
}

int main() {
    srand(time(NULL));
    int size = 100;
    vector<int> arr = generateRandomArray(size);
    Mat bubbleSortImg = Mat::zeros(640, 480, CV_8UC3);
    Mat quickSortImg = Mat::zeros(640, 480, CV_8UC3);
    Mat mergeSortImg = Mat::zeros(640, 480, CV_8UC3);
    namedWindow("Bubble Sort", WINDOW_NORMAL);
    namedWindow("Quick Sort", WINDOW_NORMAL);
    namedWindow("Merge Sort", WINDOW_NORMAL);
    resizeWindow("Bubble Sort", 640, 480);
    resizeWindow("Quick Sort", 640, 480);
    resizeWindow("Merge Sort", 640, 480);
    moveWindow("Bubble Sort", 0, 0);
    moveWindow("Quick Sort", 640, 0);
    moveWindow("Merge Sort", 1280, 0);
    bubbleSortImg.setTo(Scalar(255, 255, 255));
    quickSortImg.setTo(Scalar(255, 255, 255));
    mergeSortImg.setTo(Scalar(255, 255, 255));
    imshow("Bubble Sort", bubbleSortImg);
    imshow("Quick Sort", quickSortImg);
    imshow("Merge Sort", mergeSortImg);
    thread bubbleSortThread(bubbleSort, ref(arr), ref(bubbleSortImg), 50); // wait 50 milliseconds
    thread quickSortThread(quickSort, ref(arr), 0, size - 1, ref(quickSortImg), 50); // wait 50 milliseconds
    thread mergeSortThread(mergeSort, ref(arr), 0, size - 1, ref(mergeSortImg), 50); // wait 50 milliseconds
    bubbleSortThread.join();
    quickSortThread.join();
    mergeSortThread.join();
    waitKey(0);
    return 0;
}

如果我的回答解决了您的问题,请采纳!

引用chatGPT作答,根据代码,您的排序算法可视化使用OpenCV的图像显示窗口显示排序结果。在每个排序步骤中,您更新图像以显示排序的进度,然后使用waitKey()等待一段时间,然后继续进行下一个步骤。

问题可能在于您的排序线程正在更新图像,但图像在主线程中没有足够的时间来更新并显示。您可以尝试增加waitKey()等待时间,这将允许主线程有足够的时间来更新图像。您还可以尝试在主线程中降低排序线程的优先级,这将允许更多的时间用于主线程更新图像。

以下是代码示例:

#include <iostream>
#include <vector>
#include <thread>
#include <chrono>
#include <algorithm>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

vector<int> generateRandomArray(int size) {
    vector<int> arr(size);
    for (int i = 0; i < size; i++) {
        arr[i] = rand() % 100;
    }
    return arr;
}

void bubbleSort(vector<int>& arr, Mat& img) {
    int n = arr.size();
    for (int i = 0; i < n - 1; i++) {
        bool swapped = false;
        for (int j = 0; j < n - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                swap(arr[j], arr[j + 1]);
                swapped = true;
            }
        }
        if (swapped) {
            img.setTo(Scalar(255, 255, 255)); // clear the image
            for (int k = 0; k < n; k++) {
                line(img, Point(k * 5, 500), Point(k * 5, 500 - arr[k] * 5), Scalar(0, 0, 0), 2);
            }
            imshow("Bubble Sort", img);
            waitKey(500); // wait for 500 milliseconds
        }
    }
}

void quickSort(vector<int>& arr, int low, int high, Mat& img) {
    if (low < high) {
        int pivot = arr[high];
        int i = low - 1;
        for (int j = low; j < high; j++) {
            if (arr[j] < pivot) {
                i++;
                swap(arr[i], arr[j]);
                
            }
        }
        swap(arr[i + 1], arr[high]);
        
        img.setTo(Scalar(255, 255, 255)); // clear the image
        for (int k = 0; k < arr.size(); k++) {
            line(img, Point(k * 5, 500), Point(k * 5, 500 - arr[k] * 5), Scalar(0, 0, 0), 2);
        }
        imshow("Quick Sort", img);
        waitKey(500); // wait for 500 milliseconds
        int pivotIndex = i + 1;
        //quickSort(arr, low, pivotIndex - 1, img);
        // quickSort(arr, pivotIndex + 1, high, img);
        
        thread leftThread(quickSort, ref(arr), low, pivotIndex - 1, ref(img));
        thread rightThread(quickSort,
ref(arr), pivotIndex + 1, high, ref(img));
leftThread.join();
rightThread.join();
}
}