Select Colors in a Webcam Window and render it to a second Window. Why I can't see the selected Color in the second Window, and the Webcam View is grayscaled?

#include
#include “SDL2/SDL.h”
#include “opencv2/opencv.hpp”

Uint32 getpixel(SDL_Surface* surface, int x, int y) {
int bpp = surface->format->BytesPerPixel;
Uint8* p = (Uint8*)surface->pixels + y * surface->pitch + x * bpp;

switch (bpp) {
    case 1:
        return *p;
    case 2:
        return *(Uint16*)p;
    case 3:
        if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
            return p[0] << 16 | p[1] << 8 | p[2];
        else
            return p[0] | p[1] << 8 | p[2] << 16;
    case 4:
        return *(Uint32*)p;
    default:
        return 0;
}

}

bool isLeftMouseButtonHeld = false;
bool isRightMouseButtonHeld = false;

bool isColorInRange(Uint8 r1, Uint8 g1, Uint8 b1, Uint8 r2, Uint8 g2, Uint8 b2, int range) {
return (r1 >= r2 - range && r1 <= r2 + range) &&
(g1 >= g2 - range && g1 <= g2 + range) &&
(b1 >= b2 - range && b1 <= b2 + range);
}
//float scale = 0.5f; // Adjust the scale factor as desired

int main() {
// Create an SDL2 window
SDL_Window* mainWindow = SDL_CreateWindow(“Webcam”, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN);
if (mainWindow == nullptr) {
std::cout << "Failed to create SDL2 window: " << SDL_GetError() << std::endl;
SDL_Quit();
return -1;
}

// Create an SDL2 renderer
SDL_Renderer* mainRenderer = SDL_CreateRenderer(mainWindow, -1, SDL_RENDERER_ACCELERATED);
if (mainRenderer == nullptr) {
    std::cout << "Failed to create SDL2 renderer: " << SDL_GetError() << std::endl;
    SDL_DestroyWindow(mainWindow);
    SDL_Quit();
    return -1;
}


SDL_Window* secondWindow = SDL_CreateWindow("Selected color", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_OPENGL);
if (secondWindow == nullptr) {
    std::cout << "Failed to create second window: " << SDL_GetError() << std::endl;

// SDL_FreeSurface(secondSurface);
SDL_DestroyRenderer(mainRenderer);
SDL_DestroyWindow(mainWindow);
SDL_Quit();
return 1;
}

SDL_Renderer* secondRenderer = SDL_CreateRenderer(secondWindow, -1, SDL_RENDERER_PRESENTVSYNC);
if (secondRenderer == nullptr) {
    std::cout << "Failed to create second renderer: " << SDL_GetError() << std::endl;
    SDL_DestroyWindow(secondWindow);

// SDL_FreeSurface(secondSurface);
SDL_DestroyRenderer(mainRenderer);
SDL_DestroyWindow(mainWindow);
SDL_Quit();
return 1;
}

// SDL_Surface* imageSurface = SDL_LoadBMP(“frame.bmp”);
// if (imageSurface == nullptr) {
// std::cout << "Failed to load image: " << SDL_GetError() << std::endl;
// SDL_DestroyRenderer(mainRenderer);
// SDL_DestroyWindow(mainWindow);
// SDL_Quit();
// return 1;
// }

SDL_Surface* imageSurface = SDL_GetWindowSurface(mainWindow);
SDL_Surface* secondSurface = SDL_GetWindowSurface(secondWindow);

SDL_Rect dstRect;
dstRect.x = 0;
dstRect.y = 0;

// Set the dstRect width and height to the window size:
SDL_GetWindowSize(mainWindow, &dstRect.w, &dstRect.h);

SDL_BlitScaled(imageSurface, NULL, secondSurface, &dstRect);

SDL_Texture* imageTexture = SDL_CreateTextureFromSurface(mainRenderer, secondSurface);
if (imageTexture == nullptr) {
    std::cout << "Failed to create texture from surface: " << SDL_GetError() << std::endl;
    SDL_FreeSurface(secondSurface);
    SDL_DestroyRenderer(mainRenderer);
    SDL_DestroyWindow(mainWindow);
    SDL_Quit();
    return 1;
}

SDL_RenderCopy(mainRenderer, imageTexture, nullptr, nullptr);
SDL_RenderPresent(mainRenderer); 

// Create an OpenCV video capture using GStreamer pipeline
cv::VideoCapture capture("v4l2src device=/dev/video0 ! videoconvert ! appsink", cv::CAP_GSTREAMER);
if (!capture.isOpened()) {
    std::cout << "Failed to open webcam" << std::endl;
    SDL_DestroyTexture(imageTexture);
    SDL_DestroyRenderer(mainRenderer);
    SDL_DestroyWindow(mainWindow);
    SDL_Quit();
    return -1;
}

// SDL_RenderSetScale(secondRenderer, scale, scale);

SDL_SetRenderDrawColor(secondRenderer, 0, 0, 0, 255);
SDL_RenderClear(secondRenderer);
SDL_RenderPresent(secondRenderer);

bool quit = false;

while (!quit) {
    // Capture a frame from the webcam
    cv::Mat frame;
    capture >> frame;

    // Convert the frame to RGB format
    cv::cvtColor(frame, frame, cv::COLOR_BGR2RGB);

    // Update the SDL2 texture with the frame data
    SDL_UpdateTexture(imageTexture, nullptr, frame.data, frame.cols * 3);

// Update WindowSurface
SDL_UpdateWindowSurface(mainWindow);

    // Clear the renderer
    SDL_RenderClear(mainRenderer);

    // Copy the texture to the renderer
    SDL_RenderCopy(mainRenderer, imageTexture, nullptr, nullptr);

    // Present the renderer
    SDL_RenderPresent(mainRenderer);



    SDL_Event event;
    if (SDL_WaitEvent(&event)) {
        if (event.type == SDL_QUIT) {
            quit = true;
        } else if (event.type == SDL_MOUSEBUTTONDOWN) {
            if (event.button.button == SDL_BUTTON_LEFT) {
                isLeftMouseButtonHeld = true;
            }
            if (event.button.button == SDL_BUTTON_RIGHT) {
                isRightMouseButtonHeld = true;
            }
        } else if (event.type == SDL_MOUSEBUTTONUP) {
            if (event.button.button == SDL_BUTTON_LEFT) {
                isLeftMouseButtonHeld = false;
            }
            if (event.button.button == SDL_BUTTON_RIGHT) {
                isRightMouseButtonHeld = false;
            }
        }
    }

    if (isLeftMouseButtonHeld) {
        int x, y;
        SDL_GetMouseState(&x, &y);

        // Handle the mouse click and hold logic here
        // ...

        // Update the selectedPixel and selectedRGB values
        // ...

        // Lock the surface and process the pixel data
                Uint32 selectedPixel = getpixel(secondSurface, x, y);
                Uint8 selectedR, selectedG, selectedB;
                SDL_LockSurface(secondSurface);
                SDL_GetRGB(selectedPixel, secondSurface->format, &selectedR, &selectedG, &selectedB);
                SDL_UnlockSurface(secondSurface);
	    std::cout<<selectedR << " " << selectedG << " " << selectedB <<std::endl;
				SDL_SetRenderDrawColor(secondRenderer, 0, 0, 0, 255);
				SDL_RenderClear(secondRenderer);

				for (int i = 0; i < secondSurface->w; i++) {
				    for (int j = 0; j < secondSurface->h; j++) {
				        Uint32 currentPixel = getpixel(secondSurface, i, j);
				        Uint8 r, g, b;
			                SDL_LockSurface(secondSurface);
				        SDL_GetRGB(currentPixel, secondSurface->format, &r, &g, &b);
            				SDL_UnlockSurface(secondSurface);

				        if (isColorInRange(r, g, b, selectedR, selectedG, selectedB, 15)) {
				            SDL_SetRenderDrawColor(secondRenderer, r, g, b, 255);
				            SDL_RenderDrawPoint(secondRenderer, i, j);

// SDL_RenderDrawPoint(secondRenderer, i * scale, j * scale);
}
}
}

                SDL_RenderPresent(secondRenderer);
                SDL_RenderPresent(mainRenderer);
            }
    if (isRightMouseButtonHeld) {
        int x, y;
        SDL_GetMouseState(&x, &y);

        // Handle the mouse click and hold logic here
        // ...

        // Update the selectedPixel and selectedRGB values
        // ...

        // Lock the surface and process the pixel data
                SDL_LockSurface(secondSurface);
                Uint32 selectedPixel = getpixel(secondSurface, x, y);
                Uint8 selectedR, selectedG, selectedB;
                SDL_GetRGB(selectedPixel, secondSurface->format, &selectedR, &selectedG, &selectedB);

				SDL_SetRenderDrawColor(secondRenderer, 0, 0, 0, 255);
				SDL_RenderClear(secondRenderer);

				for (int i = 0; i < secondSurface->w; i++) {
				    for (int j = 0; j < secondSurface->h; j++) {
				        Uint32 currentPixel = getpixel(secondSurface, i, j);
				        Uint8 r, g, b;
				        SDL_GetRGB(currentPixel, secondSurface->format, &r, &g, &b);

				        if (isColorInRange(r, g, b, selectedR, selectedG, selectedB, 15)) {
				            SDL_SetRenderDrawColor(secondRenderer, r, g, b, 255);
				            SDL_RenderDrawPoint(secondRenderer, i, j);

// SDL_RenderDrawPoint(secondRenderer, i * scale, j * scale);
}
}
}

                SDL_UnlockSurface(secondSurface);
                SDL_RenderPresent(secondRenderer);
                SDL_RenderPresent(mainRenderer);
            }
        }

// }
// }

SDL_DestroyTexture(imageTexture);
SDL_FreeSurface(imageSurface);

// SDL_FreeSurface(secondSurface);
SDL_DestroyRenderer(secondRenderer);
SDL_DestroyWindow(secondWindow);
SDL_DestroyRenderer(mainRenderer);
SDL_DestroyWindow(mainWindow);
SDL_Quit();

return 0;

}

Hi, and welcome to the forum!

If you have an issue with your code, or some functionality that doesn’t work as intended etc, you might want to specify that in your post.

Or if it’s just a post where you’re sharing code your code for people to use, you might want to specify that as well, and what the code is supposed to do and can be used for.

Hi,

thank you for your help. I specified my post as a Question.

Regards Ricco