По сути, я пытаюсь прочитать прямую трансляцию с веб-камеры, разделить ее на сетку из 10 × 10 (всего 100) блоков и перестроить видеокадр в случайном порядке. С этим новым порядком блоков, составляющих кадр, я пытаюсь применить эффекты к каждому блоку в зависимости от его положения (например: оттенки серого, размытие по Гауссу и т. Д.). Выше все в порядке. Проблема, с которой я столкнулся, связана с попыткой перестроить фрейм с блоками, которые бывают как RGB, так и в оттенках серого, так как у одного есть три канала, а у другого — один, что приводит к следующей ошибке:
ошибка: (-215) channel () == CV_MAT_CN (dtype) в функции copyTo
Я сталкивался с этой ситуацией раньше и в прошлом разрешал ее, трижды дублируя один канал серой шкалы и сливаясь вместе. Однако на этот раз проблема, похоже, не решается. Я также должен отметить, что я новичок в OpenCV, поэтому я мог бы запутать что-то тривиальное. Я ожидаю, что проблема во втором случае оператора switch:
#include <imgproc_c.h>
#include <iostream>
using namespace cv;
int main( int argc, char** argv ) {
namedWindow( "Example2_10", WINDOW_AUTOSIZE );
VideoCapture cap;
if (argc==1) {
cap.open(-1); //0
} else {
cap.open(argv[1]);
}
if( !cap.isOpened() ) { // check if we succeeded
std::cerr << "Couldn't open capture." << std::endl;
return -1;
}
int frameWidth = cap.get(CV_CAP_PROP_FRAME_WIDTH);
int frameHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT);
cv::Size sb_size(frameWidth/10, frameHeight/10);
Mat frame, img_gry, img_gry_color, img_cny_color, img_cny, img_join, img_flip, temp, img_effect;
vector<Mat> img_gry_vec;
vector<Mat> img_cny_vec;
int n_cols = 10;
int n_rows = 10;
//Create multidimensional array of key pair values for positional data
std::pair<int, int> posIndex[100];
//Populate positional array with positions of every possible frame block
int counter = 0;
for(int i = 0; i < frameWidth; i += sb_size.width){
for(int j = 0; j < frameHeight; j += sb_size.height){
posIndex[counter] = std::make_pair(i, j);
counter++;
}
}
//Random shuffle positional array so as to provide random structure for compilation
std::random_shuffle(&posIndex[0], &posIndex[100]);
for(;;) {
cap >> frame;
if( frame.empty() )
break;
//Create empty grid to be populated with blocks
Mat3b grid(n_rows * sb_size.height, n_cols * sb_size.width, Vec3b(0,0,0));
//Initialise row/column and effect counters.
int rowCounter = 0;
int colCounter = 0;
int blockIndex = 0;
int effectIndex = 0;
for(int i = 0; i < frameWidth; i += sb_size.width){//iterate columns
colCounter = 0; //Reset column number on new row
rowCounter++; //Count row number
effectIndex++; //reset effect counter to equal row number on new row.
if(effectIndex == 6){
effectIndex = 1;
}
for(int j = 0; j < frameHeight; j += sb_size.height){//iterate rows
colCounter++; //Count column number: 0 - 9
blockIndex++; //Count block index: 0 - 99
//Get block position from shuffled positional array to temporary storage.
temp = Mat(frame, Rect(posIndex[blockIndex].first, posIndex[blockIndex].second, sb_size.width, sb_size.height)).clone();
Rect roi(i, j, sb_size.width, sb_size.height);//Get region of interest
effectIndex++;
//if effect index reaches five, reset to one
if(effectIndex == 6){
effectIndex = 1;
}
//Determine which effect to apply based on effect index
switch(effectIndex){
case 1:
//Copy to grid at correct roi with no effect applied.
temp.copyTo(grid(roi));
break;
case 2:
cvtColor(temp, img_gry, COLOR_BGR2GRAY);
img_gry_vec.push_back(img_gry);
img_gry_vec.push_back(img_gry);
img_gry_vec.push_back(img_gry);
cv::merge(img_gry_vec, img_gry_color);
img_gry_color.copyTo(grid(roi));
break;
case 3:
temp.copyTo(grid(roi));
break;
case 4:
GaussianBlur( temp, img_effect, Size(5, 5), 3, 3 );
img_effect.copyTo(grid(roi));
break;
case 5:
temp.copyTo(grid(roi));
break;
}
}
}
imshow( "Example3", grid);
img_gry_vec.clear();
if( cv::waitKey(33) >= 0 )
break;
}
return 0;
}
Программа работает, как и ожидалось, без применения оттенков серого. Любая помощь или указатели высоко ценится.
Задача ещё не решена.
Других решений пока нет …