2015-11-19 2 views
0

Вот часть программы «Трекбара в качестве цветовой палитры» в python, которая включает в себя opencv. Я хочу использовать его в C++.эквивалент python's [:] в C++

Моя проблема - последняя строка.

r = cv2.getTrackbarPos('R','image') 
g = cv2.getTrackbarPos('G','image') 
b = cv2.getTrackbarPos('B','image') 
img[:] = [b,g,r] 

Без этой команды у меня только черное изображение.

+1

Весь код Python делает это заменить все индексы 'img' с тремя новыми. Чтобы разбить это поэтапно: очистите 'img', измените его размер на 3 элемента, присвойте' b' индексировать 0, 'g' для индекса 1 и' r' для индекса 2. Я уверен, что C++ может выполнить эти шаги так или иначе. –

+2

Как выглядит ваш код на C++? Как хранится трэпл rgb? –

+0

Что заставляет вас полагать, что большинство конструкций Python имеют эквивалент C++? И какой стандарт C++? Надеюсь, вы кодируете, по крайней мере, C++ 11 ..... Какой компилятор, какая операционная система, какие дополнительные библиотеки (стандартный C++ 11 не имеет понятия изображений или цветов)? –

ответ

2

Вы, вероятно, хотите, чтобы установить все пиксели изображения CV_8UC3img к цвету заданной b, g и r;

Вы можете сделать это в OpenCV, как:

img.setTo(Vec3b(b, g, r)); 

или что то же самое:

img.setTo(Scalar(b, g, r)); 

В своем коде вы отсутствующие в основном все важные части:

  • бесконечный цикл (так что вы выходите из программы без refreshi ng цвет изображения)
  • присвоение нового цвета
  • вы смешиваете устаревший синтаксис C и синтаксис C++.

Это то, что вам нужно:

#include <opencv2/opencv.hpp> 
using namespace cv; 

int main(int argc, char** argv) 
{ 
    // Initialize a black image 
    Mat3b imgScribble(256, 512, Vec3b(0,0,0)); 

    namedWindow("Image", WINDOW_AUTOSIZE); 
    createTrackbar("R", "Image", 0, 255); 
    createTrackbar("G", "Image", 0, 255); 
    createTrackbar("B", "Image", 0, 255); 

    while (true) 
    { 
     int r = getTrackbarPos("R", "Image"); 
     int g = getTrackbarPos("G", "Image"); 
     int b = getTrackbarPos("B", "Image"); 

     // Fill image with new color 
     imgScribble.setTo(Vec3b(b, g, r)); 

     imshow("Image", imgScribble); 
     if (waitKey(1) == 27 /*ESC*/) break; 
    } 

    return 0; 
} 
+0

это нормально, чтобы установить b, g, r в img, но моя проблема не может увидеть результат в –

+0

@ Mr.E проверить обновленный ответ и отредактировать содержимое вашего ответа в вопросе и удалить свой ответ. – Miki

0

Я думаю, вы ищете std :: for_each(). Этот код не проверен. Он предназначен, чтобы показать концепцию, он может содержать ошибки:

// color type - use whatever you have 
using color = std::array<char, 3>; 

// prepare image, wherever you get that from 
auto img = std::vector<color>{width * height, color{{0x00, 0x00, 0x00}}}; 

// define the color we want to have: white 
char r = 0xff; 
char g = 0xff; 
char b = 0xff; 

std::for_each(std::begin(img), std::end(img), 
       [&](color& i){ 
        i = {r, g, b}; 
       }); 

Выбирая итераторы отличается от std::begin() и std::end() вы, конечно, можете выбрать любой кусочек вашего вектора.

Да, идиомы в C++ отличаются от идиом в Python.

+0

Нет, используйте C++ 11 для цикла вместо этого, он более современный и элегантный, чем for_each. –

+0

@ ErikAlapää Это верно, когда вы хотите перебирать весь диапазон. Недостатком диапазона, основанного на цикле, является то, что он не работает из коробки с фрагментами диапазона. Вопрос заключался в назначении срезов диапазона. Именно по этой причине я предложил «std :: for_each()», что гораздо более выразительно для повторения фрагментов, чем стандартный для цикла. – cdonat

+0

Правда, я просто посмотрел на фактический код, где вы использовали весь вектор. Чтобы использовать диапазон, основанный на векторном срезе, можно использовать boost :: adapters :: sliced. –

Смежные вопросы