想用c++的thread和opencv打开多个窗口实现排序算法的可视化,
可是子窗口不显示排序过程,过一会直接显示排序结果。
刚开始运行时
#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();
}
}