VS + opencv开发环境请看毛大神的文章:https://blog.csdn.net/poem_qianmo/article/details/19809337
彩色模型
数字图像处理中常用的采用模型是RGB(红,绿,蓝)模型和HSV(色调,饱和度,亮度),RGB广泛应用于彩色监视器和彩色视频摄像机,我们平时的图片一般都是RGB模型。而HSV模型更符合人描述和解释颜色的方式,HSV的彩色描述对人来说是自然且非常直观的。
HSV模型
HSV模型中颜色的参数分别是:色调(H:hue),饱和度(S:saturation),亮度(V:value)。由A. R. Smith在1978年创建的一种颜色空间, 也称六角锥体模型(Hexcone Model)。
- 色调(H:hue):用角度度量,取值范围为0°~360°,从红色开始按逆时针方向计算,红色为0°,绿色为120°,蓝色为240°。它们的补色是:黄色为60°,青色为180°,品红为300°;
- 饱和度(S:saturation):取值范围为0.0~1.0,值越大,颜色越饱和。
- 亮度(V:value):取值范围为0(黑色)~255(白色)。
因为RGB通道并不能很好地反映出物体具体的颜色信息 , 而相对于RGB空间,HSV空间能够非常直观的表达色彩的明暗,色调,以及鲜艳程度,方便进行颜色之间的对比。
下面是windows上的代码,具体可以看里面的注释:
#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <vector>
#include <cstdio>
#include <iostream>
#include <SDKDDKVer.h>
#include <stdio.h>
#include <tchar.h>
using namespace cv;
using namespace std;
void copymask(Mat image, Mat binary_image, Mat result)
{
int num_row = image.rows;
int num_col = image.cols;
for (int r = 0; r < num_row; r++) {
uchar* curr_r_open = binary_image.ptr<uchar>(r);
Vec3b* curr_r_image = image.ptr<Vec3b>(r);
Vec3b* curr_r_result = result.ptr<Vec3b>(r);
for (int c = 0; c < num_col; c++) {
if (curr_r_open[c] == 255) {
curr_r_result[c] = curr_r_image[c];
}
}
}
}
void Homography(Mat image, Mat Opened)
{
Mat element_9(9, 9, CV_8U, Scalar(1));
morphologyEx(image, Opened, MORPH_OPEN, element_9);
}
void ToHSV(Mat image, Mat result)
{
Mat hsv_image;
int num_row = image.rows;
int num_col = image.cols;
cvtColor(image, hsv_image, CV_BGR2HSV);//转HSV
for (int r = 0; r < num_row; r++) {
Vec3b *data = hsv_image.ptr<Vec3b>(r);
uchar* curr_r_result = result.ptr<uchar>(r);
for (int c = 0; c < num_col; c++) {
//if (((data[c][0] >= 0 && data[c][0] <= 10) || (data[c][0] >= 156 && data[c][0] <= 180)) && (data[c][1] >= 43)) //找红色
//if ((data[c][0] <= 124 && data[c][0] >= 100) && (data[c][1]>43) && (data[c][2] > 46)) //找蓝色
if ((data[c][0] >= 35 && data[c][0] <= 77) && (data[c][1] >= 43) && data[c][2] >= 46) { //找绿色
curr_r_result[c] = 255;
} else {
curr_r_result[c] = 0;
}
}
}
}
void setup_result(Mat image, Mat result)
{
uchar* pxvec = result.ptr<uchar>(0);
for (int r = 0; r < image.rows; r++) {
pxvec = result.ptr<uchar>(r);
for (int c = 0; c < image.cols * image.channels(); c++) {
pxvec[c] = 255;//初始化为白色
}
}
}
int main()
{
Mat image = imread("C:/Users/Administrator/Desktop/opencv_logo.jpg");
Mat hue_image;
Mat binary_image;
Mat result(image.rows, image.cols, CV_8UC3);
setup_result(image, result);//根据原图尺寸大小,将result初始化成与原图同样大小的白色图片
imshow("原图", image);//显示原图
waitKey(30);
cvtColor(image, hue_image, CV_BGR2GRAY);//将原图转为灰度图
threshold(hue_image, binary_image, 140, 255, THRESH_BINARY);// 将灰度图转为二值图
ToHSV(image, binary_image);//将RGB转为HSV
Homography(binary_image, binary_image);//形态学开运算
copymask(image, binary_image, result);//利用二值图(binary_image)上目标颜色的轮廓,将原图(image)上相应坐标位置颜色值赋给result
imshow("result", result);
waitKey(30);
getchar();
return 0;
}
效果: