opencv根据颜色提取目标

来源:互联网 发布:数据分析师学什么专业 编辑:程序博客网 时间:2024/05/16 08:32

opencv根据颜色提取目标

方法一:在RGB空间提取

用软件取色器选取要提取目标的颜色,记下其RGB值。

#include <```>using namespace std;using namespace cv;Vec3b target = Vec3b(0, 255, 0);//目标颜色RGB值bool getDistance(const Vec3b& color){    return abs(color[2] - target[2]) < 255 &&        abs(color[1] - target[1]) < 80 &&        abs(color[0] - target[0]) < 255;}int main(int argc, char *argv[]){    //Mat src = imread("C:\\Users\\lcg\\Desktop\\000001_20151209_00097067.BMP");    Mat src = imread("C:\\Users\\lcg\\Desktop\\watch44.jpg");    Mat resized;    Mat result;    int ratio;    if (src.size().width < 200)        ratio = 1;    else        ratio = src.size().width / 200;    if (!src.data)    {        fprintf(stderr, "error load pic\n");        return -1;    }    resize(src, resized, Size(src.cols , src.rows));    resize(src, resized, Size(src.cols / ratio, src.rows / ratio));    resized = src.clone();    result = resized.clone();    Mat_ <cv::Vec3b>::const_iterator it = resized.begin<Vec3b>();    Mat_ <cv::Vec3b>::const_iterator itend = resized.end<Vec3b>();    Mat_ <cv::Vec3b>::iterator itout = result.begin<Vec3b>();    for (; it != itend; ++it, ++itout)    {        if (getDistance(*it))        {        }        else        {            (*itout)[0] = 255;            (*itout)[1] = 255;            (*itout)[2] = 255;        }    }    namedWindow("src");    imshow("src", resized);    namedWindow("resized");    imshow("resized", result);    waitKey(0);    return 0;}

说明1:

bool getDistance(const Vec3b& color){    return abs(color[2] - target[2]) < 255 &&        abs(color[1] - target[1]) < 80 &&        abs(color[0] - target[0]) < 255;}

此函数简单判断遍历到的像素的点的RGB值和目标值的距离是否满足要求。

说明2:

    Mat_ <cv::Vec3b>::const_iterator it = resized.begin<Vec3b>();    Mat_ <cv::Vec3b>::const_iterator itend = resized.end<Vec3b>();    Mat_ <cv::Vec3b>::iterator itout = result.begin<Vec3b>();    for (; it != itend; ++it, ++itout)    {        if (getDistance(*it))        {        }        else        {            (*itout)[0] = 255;            (*itout)[1] = 255;            (*itout)[2] = 255;        }    }

利用迭代器来遍历访问图像中的像素,Vec3b类型的迭代器,访问其三通道的值

(*itout)[0] = 255;//前面一定要加括号,注意写法。不然运行不会报错但是结果不正确

方法二:HSV颜色空间

import numpy as npfrom PIL import ImagepicPath = "C:\\Users\\lcg\\Desktop\\X\\pic\\"savePathBlue = "C:\\Users\\lcg\\Desktop\\stract\\blue\\"def blue():    for file in os.listdir(picPath):        pic_file_name = picPath + file        img = cv2.imread(pic_file_name)        print "filename: " + str(file)        print "img.shape: " + str(img.shape)        hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)        #设置蓝色阈值        lower_blue = np.array([100,43,46])        upper_blue = np.array([124,255,255])        mask = cv2.inRange(hsv,lower_blue,upper_blue)        res = cv2.bitwise_and(img,img,mask=mask)        '''        cv2.imshow('frame', img)        cv2.imshow('mask', mask)        cv2.imshow('res', res)        cv2.waitKey(0)        cv2.destroyAllWindows()        '''        #这里是将背景的黑色变为白色,遍历像素的方式实现的,这样很慢,但是我还不会更好的方法        for y in range(res.shape[1]):            for x in range(res.shape[0]):                i = 0                for z in range(3):                    if res.item(x,y,z) == 0 :                        i = i + 1                if i == 3:                    res[x, y] = (255, 255, 255)        #cv2.imshow('res', res)        cv2.imwrite(savePathBlue+file,res)        #cv2.waitKey(0)if __name__ == "__main__":    #blue()

这是原图
这是提取之后的图

颜色范围是根据查表得到的h空间的分布,但是纸上得来终觉浅,决定遍历一下图上的所有像素点,观察一下其h值得变化范围,验证我的范围是否有问题。
决定用python可视化的方法将像素点的散点图画出来,大致上看一下。

0 0
原创粉丝点击