Вопрос

I am using FreeMat, and I have an RGB picture which is a 3D matrix contains the columns and rows of the pictures and the RGB values for each pixel.

Since there is not an intrinsic function to convert RGB picture to YIQ, I have implement one. I came up with this code:

Assume I have a 3D array, image_rgb:

matrix = [0.299 0.587 0.114;
0.596 -0.274 -0.322;
0.211 -0.523 0.312];
row = 1:length(image_rgb(:,1,1));
col = 1:length(image_rgb(1,:,1));
p = image_rgb(row,col,:);

%Here I have the problem
mage_yiq(row,col,:) = matrix*image_rgb(row,col,:);

max_y = max (max(image_yiq(:,:,1)));
max_i = max (max(image_yiq(:,:,2)));
max_q = max (max(image_yiq(:,:,3)));

%Renormalize the image again after the multipication
% to [0,1].
image_yiq(:,:,1) = image_yiq(:,:,1)/max_y;
image_yiq(:,:,2) = image_yiq(:,:,2)/max_i;
image_yiq(:,:,3) = image_yiq(:,:,3)/max_q;

I can't understand why the matrix multiplication fails. I want the code to be nice and not just to, multiply the matrix by hand...

Это было полезно?

Решение

You try to multiple a 3D array with the matrix you created which is not a proper matrix multiplication. You should unfold your image data to a 3-by-m*n matrix and multiply it with your custom matrix.

Here is a solution for applying custom color space conversions to an RGB image. I used the matrix that you provided and compared it to the built-in YIQ transform.

%# Define the conversion matrix
matrix = [0.299  0.587  0.114;
          0.596 -0.274 -0.322;
          0.211 -0.523  0.312];

%# Read your image here
rgb = im2double(imread('peppers.png'));
subplot(1,3,1), imshow(rgb)
title('RGB')


%# Convert using unfolding and folding
[m n k] = size(rgb);

%# Unfold the 3D array to 3-by-m*n matrix
A = permute(rgb, [3 1 2]);
A = reshape(A, [k m*n]);

%# Apply the transform
yiq = matrix * A;

%# Ensure the bounds
yiq(yiq > 1) = 1;
yiq(yiq < 0) = 0;

%# Fold the matrix to a 3D array
yiq = reshape(yiq, [k m n]);
yiq = permute(yiq, [2 3 1]);

subplot(1,3,2), imshow(yiq)
title('YIQ (with custom matrix)')


%# Convert using the rgb2ntsc method
yiq2 = rgb2ntsc(rgb);
subplot(1,3,3), imshow(yiq2)
title('YIQ (built-in)')

YIQ results

Note that k will be 3 for RGB images. See the size of the matrices after each statement. And don't forget to convert your image to double.

Другие советы

It is possible to do this with Imagemagick using the same matrix and -color-matrix function:

Input:

enter image description here

convert peppers_tiny.png -color-matrix \
" \
0.299 0.587 0.114 \
0.596 -0.274 -0.322 \
0.211 -0.523 0.312 \
" \
peppers_tiny_yiq.png

enter image description here

But this is not a true sRGB to YIQ transformation.

Here is an sRGB to YIQ transformation, showing the YIQ as if RGB:

convert peppers_tiny.png -colorspace YIQ -separate \
-set colorspace sRGB -combine peppers_tiny_yiq2.png

enter image description here

Here is the same but swapping the first two channels:

convert peppers_tiny.png -colorspace YIQ -separate \
-swap 0,1 -set colorspace sRGB -combine peppers_tiny_yiq3.png

enter image description here

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top