重慶門戶網(wǎng)站開(kāi)發(fā)報(bào)價(jià)seo網(wǎng)站結(jié)構(gòu)優(yōu)化的方法
HSV通道的含義
HSV通道是指圖像處理中的一種顏色模型,它由色調(diào)(Hue)、飽和度(Saturation)和明度(Value)三個(gè)通道組成。色調(diào)表示顏色的種類,飽和度表示顏色的純度或鮮艷程度,明度表示顏色的亮度。HSV通道常用于圖像處理中的顏色分析、顏色過(guò)濾、顏色調(diào)整等任務(wù),它相對(duì)于其他顏色模型具有更直觀和易于調(diào)節(jié)的特點(diǎn),因此被廣泛應(yīng)用于計(jì)算機(jī)視覺(jué)和圖像處理的領(lǐng)域。
Halcon算子例程
read_image (Image, 'D:/lena.jpg')
decompose3 (Image, ImageR, ImageG, ImageB)
trans_from_rgb (ImageR, ImageG, ImageB, ImageH, ImageS, ImageV, 'hsv')
trans_to_rgb (ImageH, ImageS, ImageV, ImageR1, ImageG1, ImageB1, 'hsv')
compose3 (ImageR1, ImageG1, ImageB1, MultiChannelImage)
這里先將三通道RGB三通道拆開(kāi)成單獨(dú)的通道,再將RGB與HSV通道互相轉(zhuǎn)換,最后將三通道圖像合并成RGB圖像。
Halcon的圖像效果是:
源代碼實(shí)現(xiàn)
RGB轉(zhuǎn)成HSV
這里需要注意的是,halcon這里將HSV三通道的取值范圍作了說(shuō)明,H通道的數(shù)值范圍是0到2*pi,S通道的數(shù)值范圍是0到1,V通道的數(shù)值范圍是0到1。而常用的圖像為BYTE字節(jié)型,數(shù)值范圍是0到255,這里對(duì)公式做了修改,使Matlab得出的圖像數(shù)據(jù)范圍是0到255,可以直接顯示,這里可以從matlab的workspace中看到計(jì)算過(guò)程。
以下便是使用Matlab實(shí)現(xiàn)trans_from_rgb的效果
trans_from_rgb (ImageR, ImageG, ImageB, ImageH, ImageS, ImageV, 'hsv')
Matlab源碼
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%代碼--RGB通道轉(zhuǎn)HSV通道
%時(shí)間:2023.9
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clc;
image=imread('D:\lena.jpg');
[height,width,channels]=size(image);
figure;
imshow(image);
title('rgb-image');
image_R=image(:,:,1);
image_R=double(image_R);
image_G=image(:,:,2);
image_G=double(image_G);
image_B=image(:,:,3);
image_B=double(image_B);%%%轉(zhuǎn)化成HSV通道
H_image = zeros(height,width);
S_image = zeros(height,width);
V_image = zeros(height,width);%%RGB轉(zhuǎn)成HSV
for i=1:1:heightfor j=1:1:width%%%計(jì)算三通道的最大最小值計(jì)算image_matrix = [image_R(i,j), image_G(i,j), image_B(i,j)];maxValue = max(image_matrix);minValue = min(image_matrix);V_image(i,j) = maxValue;if(maxValue == minValue)S_image(i,j) = 0;H_image(i,j) = 0;else%%%計(jì)算飽和度S_image(i,j) = (maxValue - minValue)*255/minValue;%%%計(jì)算H通道if(maxValue == image_R(i,j))H_image(i,j) = 42.5.*(image_G(i,j) - image_B(i,j))./(maxValue - minValue);elseif(maxValue == image_G(i,j))H_image(i,j) = 42.5 * (2 + (image_B(i,j) - image_R(i,j)) / (maxValue - minValue));elseif(maxValue == image_B(i,j)) H_image(i,j) = 42.5 * (4 + (image_R(i,j) - image_G(i,j)) / (maxValue - minValue));endendend
end%%%RGB要取整
H_image = uint8(H_image);
S_image = uint8(S_image);
V_image = uint8(V_image);figure;
imshow(H_image);
title('H_image');figure;
imshow(S_image);
title('S_image');figure;
imshow(V_image);
title('V_image');
最終實(shí)現(xiàn)的效果是:
最終驗(yàn)證的效果與halcon效果一致;
同時(shí),以上代碼采用C++實(shí)現(xiàn)的話如下所示,這里為了保證精度,輸出結(jié)果采用的是double類型,但是范圍也是0到255之間,要顯示的話,需要轉(zhuǎn)化為unsigned char類型:
C++源碼
//將RGB圖像轉(zhuǎn)化成HSV圖像
/*
輸入: rData : r通道圖像gData : g通道圖像bData : b通道圖像
輸出: hDoubleData : h通道圖像, h通道采用double類型,保留精度sDoubleData : s通道圖像,s通道采用double類型,保留精度vDoubleData : v通道圖像,v通道采用double類型,保留精度
*/
void trans_from_rgb(unsigned char *rData, unsigned char *gData, unsigned char *bData, double *hDoubleData, double *sDoubleData, double *vDoubleData, int height, int width)
{if ((height <= 0) || (width <= 0))return;//在函數(shù)外部分配好內(nèi)存空間if (rData == NULL || gData == NULL || bData == NULL || hDoubleData == NULL || sDoubleData == NULL || vDoubleData == NULL)return;int i;unsigned char minValue,maxValue;for (i = 0; i < width * height; i++){//V通道數(shù)據(jù),三通道的最大值maxValue = std::max(std::max(rData[i], gData[i]), bData[i]);minValue = std::min(std::min(rData[i], gData[i]), bData[i]);vDoubleData[i] = maxValue;if (maxValue == minValue){sDoubleData[i] = 0;hDoubleData[i] = 0;}else{//S通道sDoubleData[i] = (maxValue - minValue)*255.0 / maxValue;//H通道if (maxValue == rData[i])hDoubleData[i] = 42.5 * (gData[i] - bData[i]) / (maxValue - minValue); else if (maxValue == gData[i])hDoubleData[i] = 42.5 * (2 + (bData[i] - rData[i]) / (maxValue - minValue));else if (maxValue == bData[i])hDoubleData[i] = 42.5 * (4 + (rData[i] - gData[i]) / (maxValue - minValue));}}
}
HSV轉(zhuǎn)成RGB
halcon給出的公式說(shuō)明為:
Matlab源碼
同樣的,采用Matlab實(shí)現(xiàn):
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%代碼--HSV通道轉(zhuǎn)RGB通道
%時(shí)間:2023.9
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clc;
image1=imread('D:\lena.jpg');
[height,width,channels]=size(image1);
image_H=double(image1);
image2=imread('E:\S_image.bmp');
image_S=double(image2);
image3=imread('E:\V_image.bmp');
image_V=double(image3);%%%轉(zhuǎn)化成RGB通道
R_image = zeros(height,width);
G_image = zeros(height,width);
B_image = zeros(height,width);%%%HSV轉(zhuǎn)成RGB
for i=1:1:heightfor j=1:1:widthif(image_S(i,j) == 0)R_image(i,j) = image_V(i,j);G_image(i,j) = image_V(i,j);B_image(i,j) = image_V(i,j);else%%Hi = floor(image_H(i,j)*2*pi/255/deg2rad(60)); %%歸一化到0到2*piHi = floor(image_H(i,j)*0.025);Hf = image_H(i,j)*0.025 - Hi;%%%%根據(jù)H的值,將C,X,m分別對(duì)應(yīng)到RGB三個(gè)分量上if(Hi == 0)R_image(i,j) = image_V(i,j);G_image(i,j) = image_V(i,j) * (1 - image_S(i,j)/255*(1-Hf));B_image(i,j) = image_V(i,j) * (1 - image_S(i,j)/255);elseif(Hi == 1)R_image(i,j) = image_V(i,j) * (1 - image_S(i,j)/255*Hf);G_image(i,j) = image_V(i,j);B_image(i,j) = image_V(i,j) * (1 - image_S(i,j)/255);elseif(Hi == 2)R_image(i,j) = image_V(i,j) * (1 - image_S(i,j)/255);G_image(i,j) = image_V(i,j);B_image(i,j) = image_V(i,j) * (1 - image_S(i,j)/255*(1-Hf));elseif(Hi == 3)R_image(i,j) = image_V(i,j) * (1 - image_S(i,j)/255);G_image(i,j) = image_V(i,j) * (1 - image_S(i,j)/255*Hf);B_image(i,j) = image_V(i,j);elseif(Hi == 4)R_image(i,j) = image_V(i,j) * (1 - image_S(i,j)/255*(1-Hf));G_image(i,j) = image_V(i,j) * (1 - image_S(i,j)/255);B_image(i,j) = image_V(i,j);elseif(Hi == 5)R_image(i,j) = image_V(i,j);G_image(i,j) = image_V(i,j) * (1 - image_S(i,j)/255);B_image(i,j) = image_V(i,j) * (1 - image_S(i,j)/255*Hf);endendend
end%%%RGB要取整
R_image = uint8(R_image);
G_image = uint8(G_image);
B_image = uint8(B_image);figure;
imshow(R_image);
title('R_image');figure;
imshow(G_image);
title('G_image');figure;
imshow(B_image);
title('B_image');
最終實(shí)現(xiàn)的效果是:
可以看出,與Halcon效果一致;
C++源碼
同樣的,采用C++實(shí)現(xiàn):
//將HSV圖像轉(zhuǎn)化成RGB圖像
/*
輸入: hDoubleData : h通道圖像 ,h通道采用double類型,保留精度sDoubleData : s通道圖像 ,s通道采用double類型,保留精度vDoubleData : v通道圖像 ,v通道采用double類型,保留精度
輸出: rDoubleData : r通道圖像 ,r通道采用double類型,保留精度gDoubleData : g通道圖像 ,g通道采用double類型,保留精度bDoubleData : b通道圖像 ,b通道采用double類型,保留精度
*/
void trans_to_rgb(double *hDoubleData, double *sDoubleData, double *vDoubleData, double *rDoubleData, double *gDoubleData, double *bDoubleData, int height, int width)
{if ((height <= 0) || (width <= 0))return;if (rDoubleData == NULL || gDoubleData == NULL || bDoubleData == NULL || hDoubleData == NULL || sDoubleData == NULL || vDoubleData == NULL)return;int i;double Hi, Hf;for (i = 0; i < width * height; i++){if (sDoubleData[i] > 0){Hi = floor(hDoubleData[i] * 0.025);Hf = hDoubleData[i] * 0.025 - Hi;if (Hi == 0){rDoubleData[i] = vDoubleData[i];gDoubleData[i] = vDoubleData[i] * (1 - sDoubleData[i] / 255.0*(1 - Hf));bDoubleData[i] = vDoubleData[i] * (1 - sDoubleData[i] / 255.0);}else if (Hi == 1){rDoubleData[i] = vDoubleData[i] * (1 - sDoubleData[i] / 255.0 * Hf);gDoubleData[i] = vDoubleData[i];bDoubleData[i] = vDoubleData[i] * (1 - sDoubleData[i] / 255.0);}else if (Hi == 2){rDoubleData[i] = vDoubleData[i] * (1 - sDoubleData[i] / 255.0);gDoubleData[i] = vDoubleData[i];bDoubleData[i] = vDoubleData[i] * (1 - sDoubleData[i] / 255.0*(1 - Hf));}else if (Hi == 3){rDoubleData[i] = vDoubleData[i] * (1 - sDoubleData[i] / 255.0);gDoubleData[i] = vDoubleData[i] * (1 - sDoubleData[i] / 255.0 * Hf);bDoubleData[i] = vDoubleData[i];}else if (Hi == 4){rDoubleData[i] = vDoubleData[i] * (1 - sDoubleData[i] / 255.0*(1 - Hf));gDoubleData[i] = vDoubleData[i] * (1 - sDoubleData[i] / 255.0);bDoubleData[i] = vDoubleData[i];}else if (Hi == 5){rDoubleData[i] = vDoubleData[i];gDoubleData[i] = vDoubleData[i] * (1 - sDoubleData[i] / 255.0);bDoubleData[i] = vDoubleData[i] * (1 - sDoubleData[i] / 255.0 * Hf);}}else{rDoubleData[i] = gDoubleData[i] = bDoubleData[i] = vDoubleData[i];}}
}
通道拆分與合并C++源代碼實(shí)現(xiàn)
三通道拆分
Halcon中,拆分三通道的算子為:
decompose3 (Image, ImageR, ImageG, ImageB)
對(duì)應(yīng)的拆分三通道圖像的C++函數(shù)為:
//拆分三通道圖像
/*
輸入: srcData : 三通道圖像,內(nèi)存排列方式是BGRBGRBGR......
輸出: rData : r通道圖像gData : g通道圖像bData : b通道圖像
*/
void decompose3(unsigned char *srcData, unsigned char *rData, unsigned char *gData, unsigned char *bData, int height, int width)
{if ((height <= 0) || (width <= 0))return;if (srcData == NULL || rData == NULL || gData == NULL || bData == NULL)return;int i;
#pragma omp parallel for num_threads(3)for (i = 0; i < width * height; i++){bData[i] = srcData[3 * i];gData[i] = srcData[3 * i + 1];rData[i] = srcData[3 * i + 2];}
}
三通道合并
Halcon中,拆分三通道的算子為:
compose3 (ImageR1, ImageG1, ImageB1, MultiChannelImage)
對(duì)應(yīng)的合并三通道圖像的C++函數(shù)為:
//合并三通道圖像
/*
輸入: rData : r通道圖像gData : g通道圖像bData : b通道圖像
輸出: bgrData:彩色圖像,合并成BGRBGR.....排列
*/
void compose3(unsigned char *rData, unsigned char *gData, unsigned char *bData, unsigned char *bgrData, int height, int width)
{if ((height <= 0) || (width <= 0))return;if (bgrData == NULL || rData == NULL || gData == NULL || bData == NULL)return;int i;
#pragma omp parallel for num_threads(3)for (i = 0; i < width * height; i++){bgrData[3 * i] = bData[i];bgrData[3 * i + 1] = gData[i];bgrData[3 * i + 2] = rData[i];}
}