图像处理——BGR2HSV

不问归期 提交于 2019-12-15 01:21:36

图像处理——BGR2HSV

将BGR彩色转换为HSV彩色图像。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
python代码:

import cv2
import numpy as np

def BGR2HSV(_img):
    img = _img / 255.0

    hsv_img = np.zeros_like(img, dtype=np.float32)

    # get max and min
    max_v = np.max(img, axis=2).copy()
    min_v = np.min(img, axis=2).copy()
    min_arg = np.argmin(img, axis=2)       # 最小值在数组中占的位置

    # H
    hsv_img[..., 0][np.where(max_v == min_v)] = 0
    ## min = B
    ind = np.where(min_arg == 0)
    hsv_img[..., 0][ind] = 60 * (img[..., 1][ind] - img[..., 2][ind]) / (max_v[ind] - min_v[ind]) + 60
    ## min = R
    ind = np.where(min_arg == 2)
    hsv_img[..., 0][ind] = 60 * (img[..., 0][ind] - img[..., 1][ind]) / (max_v[ind] - min_v[ind]) + 120
    ## min = G
    ind = np.where(min_arg == 1)
    hsv_img[..., 0][ind] = 60 * (img[..., 2][ind] - img[..., 0][ind]) / (max_v[ind] - min_v[ind]) + 300
    # S
    hsv_img[..., 1] = max_v.copy() - min_v.copy()
    # V
    hsv_img[..., 2] = max_v.copy()

    return hsv_img

def BGR2HSV_v2(img):
    img = img / 255.0

    img_hsv = np.zeros([H, W, C])
    for i in range(H):
        for j in range(W):
            max = np.max(img[i, j, :])
            min = np.min(img[i, j, :])
            if min == max:
                img_hsv[i, j, 0] = 0
            elif min == img[i, j, 0]:        # min = B
                img_hsv[i, j, 0] = 60 * (img[i, j, 1] - img[i, j, 2]) / (max - min) + 60
            elif min == img[i, j, 2]:        # min = R
                img_hsv[i, j, 0] = 60 * (img[i, j, 0] - img[i, j, 1]) / (max - min) + 180
            elif min == img[i, j, 1]:
                img_hsv[i, j, 0] = 60 * (img[i, j, 2] - img[i, j, 0]) / (max - min) + 300
            img_hsv[i, j, 1] = max - min
            img_hsv[i, j, 2] = max

    return img_hsv

def HSV2RGB(_img, hsv):
    '''
    :param _img: GBR图
    :param hsv: hsv图
    :return:
    '''
    img = _img / 255.
    max_v = np.max(img, axis=2).copy()
    min_v = np.min(img, axis=2).copy()

    img_rgb = np.zeros_like(img)

    H = hsv[..., 0]
    S = hsv[..., 1]
    V = hsv[..., 2]

    C = S
    H_temp = H/60.
    X = C * (1 - np.abs(H_temp % 2 - 1))
    Z = np.zeros_like(H)

    vals = [[Z, X, C],
            [Z, C, X],
            [X, C, Z],
            [C, X, Z],
            [C, Z, X],
            [X, Z, C]]

    for i in range(6):
        ind = np.where((i <= H_temp) & (H_temp<(i+1)))
        img_rgb[..., 0][ind] = (V - C)[ind] + vals[i][0][ind]
        img_rgb[..., 1][ind] = (V - C)[ind] + vals[i][1][ind]
        img_rgb[..., 2][ind] = (V - C)[ind] + vals[i][2][ind]

    img_rgb[np.where(max_v == min_v)] = 0
    img_rgb = np.clip(img_rgb, 0, 1)
    img_rgb = (img_rgb * 255).astype(np.uint8)

    return img_rgb
    
    img = cv2.imread("../imori.jpg")
	hsv = BGR2HSV(img)
	hsv[..., 0] = (hsv[..., 0] + 180) % 360       # 反相
	rgb = HSV2RGB(img, hsv)
	cv2.imshow("result", rgb)
	cv2.waitKey(0)
	cv2.destroyAllWindows()

C++代码:

#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>

//BGR->HSV
cv::Mat BGR2HSV(cv::Mat img) {
	int height = img.rows;
	int width = img.cols;

	float r, g, b;
	float h, s, v;
	float _max, _min;

	cv::Mat hsv = cv::Mat::zeros(height, width, CV_32FC3);

	for (int y = 0; y < height; y++) {
		for (int x = 0; x < width; x++) {
			r = (float)img.at<cv::Vec3b>(y, x)[2] / 255;
			g = (float)img.at<cv::Vec3b>(y, x)[1] / 255;
			b = (float)img.at<cv::Vec3b>(y, x)[0] / 255;

			_max = fmax(r, fmax(g, b));
			_min = fmin(r, fmin(g, b));

			// H
			if (_min == _max){
				h = 0;
			}
			else if (_min == b) {
				h = 60 * (g - r) / (_max - _min) + 60;
			}
			else if (_min == r) {
				h = 60 * (b - g) / (_max - _min) + 180;
			}
			else if (_min == g) {
				h = 60 * (r - b) / (_max - _min) + 300;
			}
			// V
			v = _max;
			// S
			s = _max - _min;

			hsv.at<cv::Vec3f>(y, x)[0] = h;
			hsv.at<cv::Vec3f>(y, x)[1] = s;
			hsv.at<cv::Vec3f>(y, x)[2] = v;
		}
	}
	return hsv;
}

cv::Mat HSV2BGR(cv::Mat hsv) {
	int height = hsv.rows;
	int width = hsv.cols;

	float h, s, v;
	double c, h_, x_;
	double r, g, b;


	cv::Mat out = cv::Mat::zeros(height, width, CV_8UC3);

	for (int y = 0; y < height; y++)
	{
		for (int x = 0; x < width; x++) {
			h = hsv.at<cv::Vec3f>(y, x)[0];
			s = hsv.at<cv::Vec3f>(y, x)[1];
			v = hsv.at<cv::Vec3f>(y, x)[2];

			c = s;		
			h_ = h / 60;
			x_ = c * (1 - abs(fmod(h_, 2) - 1));

			r = g = b = v - c;

			if (h_ < 1) {
				r += c;
				g += x_;
			}
			else if (h_ < 2) {
				r += x_;
				g += c;
			}
			else if (h_ < 3) {
				g += c;
				b += x_;
			}
			else if (h_ < 4) {
				g += x_;
				b += c;
			}
			else if (h_ < 5) {
				r += x_;
				b += c;
			}
			else if (h_ < 6){			
				r += c;
				b += x_;
			}

			out.at<cv::Vec3b>(y, x)[0] = (uchar)(b * 255);
			out.at<cv::Vec3b>(y, x)[1] = (uchar)(g * 255);
			out.at<cv::Vec3b>(y, x)[2] = (uchar)(r * 255);
		}
	}
	return out;
}


cv::Mat inverse_hue(cv::Mat hsv) {
	int height = hsv.rows;
	int width = hsv.cols;
	for (int y = 0; y < height; y++) {
		for (int x = 0; x < width; x++) {
			hsv.at<cv::Vec3f>(y, x)[0] = fmod((hsv.at<cv::Vec3f>(y, x)[0] + 180), 360);
		}
	}
	return hsv;
}


int main(int argc, const char* argv[]) {
	cv::Mat img = cv::imread("./imori.jpg", cv::IMREAD_COLOR);
	cv::Mat hsv = BGR2HSV(img);
	cv::Mat inverse_hsv = inverse_hue(hsv);
	cv::Mat out = HSV2BGR(inverse_hsv);
	cv::imshow("sample", out);
	cv::waitKey(0);
	cv::destroyAllWindows();

	return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!