OpenCV获取彩色图像某一通道的最大连通域

原文链接 作者:Augusdi

 

#include <stdio.h>
#include <cv.h> 
#include <highgui.h> 
#include <cxcore.h> 
#include <vector> 
#include <algorithm> 

#pragma comment(lib, "cv.lib")
#pragma comment(lib, "cxcore.lib")
#pragma comment(lib, "highgui.lib")

using namespace std; 

int main()
{
    IplImage *src = cvLoadImage("wind.png", CV_LOAD_IMAGE_COLOR);//读取图像文件
    cvNamedWindow("origin");
    cvShowImage("origin", src);    // 显示原始图像
    // 摄像机保存的图像是32位的,有R,G,B和Alpha通道
    // 图像中实际存储顺序是B,G,R
    IplImage *blue = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);    // 制作一个单通道图像
    IplImage *green = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);    // 制作一个单通道图像
    IplImage *red = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);        // 制作一个单通道图像
    cvSplit(src, blue, green, red, NULL);    // 分割颜色通道
    cvSmooth(green, green, CV_MEDIAN, 7);    // 7*7中值滤波
    cvThreshold(green, green, 0.0, 255.0, CV_THRESH_BINARY | CV_THRESH_OTSU);    // OTSU法二值化
    {
        IplConvKernel *element = cvCreateStructuringElementEx(5, 5, 0, 0, CV_SHAPE_ELLIPSE); // 定义形态学结构指针
        cvMorphologyEx(green, green, NULL, element, CV_MOP_OPEN);        // 开运算,去除比结构元素小的亮点
        cvReleaseStructuringElement(&element);
    }
    cvNamedWindow("binary");
    cvShowImage("binary", green);    // 显示二值化图像
    {
        int color = 254;            // 从254开始,因此连通域不能多于253个
        CvSize sz = cvGetSize(green);
        int w, h;
        for (w = 0; w < sz.width; w++)
        {
            for (h = 0; h < sz.height; h++)
            {
                if (color > 0)
                {
                    if (CV_IMAGE_ELEM(green, unsigned char, h, w) == 255)
                    {
                        cvFloodFill(green, cvPoint(w, h), CV_RGB( color,color,color)); // 把各连通域标记上颜色
                        color--;
                    }
                }
            }
        }
        cvNamedWindow("labeled");
        cvShowImage("labeled", green);    // 显示标记后的图像
        int colorsum[255] = {0};
        for (w = 0; w < sz.width; w++)
        {
            for (h=0; h<sz.height; h++)
            {
                if (CV_IMAGE_ELEM(green, unsigned char, h, w) > 0)    // 不对0值计数,不可能为255
                {
                    colorsum[CV_IMAGE_ELEM(green, unsigned char, h, w)]++; // 统计每种颜色的数量
                }
            }
        }
        std::vector<int> v1(colorsum, colorsum + 255);    // 用数组初始化vector
        int maxcolorsum = max_element(v1.begin(), v1.end()) - v1.begin(); // 求出最多数量的颜色
        for (w = 0; w < sz.width; w++)
        {
            for (h = 0; h < sz.height; h++)
            {
                if (CV_IMAGE_ELEM(green, unsigned char, h, w) == maxcolorsum)
                {
                    CV_IMAGE_ELEM(green, unsigned char, h, w) = 255;    // 只把最多数量的颜色标为255
                }
                else
                {
                    CV_IMAGE_ELEM(green, unsigned char, h, w) = 0;        // 其他标为0
                }
            }
        }
        cvNamedWindow("最大连通域");
        cvShowImage("最大连通域", green);    // 显示最大连通域
    }
    cvReleaseImage(&src);
    cvReleaseImage(&blue);
    cvReleaseImage(&green);
    cvReleaseImage(&red);
    cvWaitKey(-1);

return 0;
}

--------------------- 
作者:Augusdi 
来源:CSDN 
原文:https://blog.csdn.net/Augusdi/article/details/9009087 
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值