数据图像实验三:图像统计与结构c++实现

实验3.1:直方图均衡化

实现图像的直方图均衡化算法,可以处理8位、任意通道数的图像。

实验3.2 快速连通域

实现图像的快速连通域算法,可以提取出图像中的连通域,并将不同连通域用不同颜色显示。
这里写图片描述

3.1代码:

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

using namespace cv;
using namespace std;

Mat mapping(Mat simg)
{
    Mat dimg;
    simg.copyTo(dimg);
    Mat *temp = new Mat[simg.channels()];
    split(simg, temp);
    int *a = new int[256];
    int *b = new int[256];

    for (int n = 0; n < simg.channels(); n++)
    {
        for (int i = 0; i < 256; i++)
        {
            a[i] = 0;
            b[i] = 0;
        }
        for (int x = 0; x < temp[n].rows; x++)
        {
            for (int y = 0; y < temp[n].cols; y++)
            {
                a[(int)temp[n].ptr(x, y)[0]] = a[(int)temp[n].ptr(x, y)[0]] + 1;
            }
        }
        for (int j = 0; j < 256; j++)
        {
            for (int i = 0; i < j; i++)
            {
                b[j] = b[j] + a[i];
            }
            double d = b[j];
            b[j]=d/ (temp[n].rows*temp[n].cols) * 255;
        }
        for (int x = 0; x < temp[n].rows; x++)
        {
            for (int y = 0; y < temp[n].cols; y++)
            {
                dimg.ptr(x, y)[n]= b[(int)temp[n].ptr(x, y)[0]];
            }
        }
    }
    return dimg;
}

int main()
{
    Mat img = imread("god.jpg");
    imshow("均衡前", img);
    imshow("均衡后", mapping(img));
    waitKey();
    return 0;
}

3.2代码:

#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>
#include<iostream>
#include <string>  
#include <list>  
#include <vector>  
#include <map>  

using namespace cv;
using namespace std;

void pass(const Mat& simg, Mat& dimg)
{
    if (simg.empty() ||
        simg.type() != CV_8UC1)
    {
        return;
    }

    dimg.release();
    simg.convertTo(dimg, CV_32SC1);

    int label = 1;
    vector<int> labelSet;
    labelSet.push_back(0);    
    labelSet.push_back(1);  

    int rows = simg.rows - 1;
    int cols = simg.cols - 1;
    for (int i = 1; i < rows; i++)
    {
        int* data_preRow = dimg.ptr<int>(i - 1);
        int* data_curRow = dimg.ptr<int>(i);
        for (int j = 1; j < cols; j++)
        {
            if (data_curRow[j] == 1)
            {
                vector<int> neighborLabels;
                neighborLabels.reserve(2);
                int leftPixel = data_curRow[j - 1];
                int upPixel = data_preRow[j];
                if (leftPixel > 1)
                {
                    neighborLabels.push_back(leftPixel);
                }
                if (upPixel > 1)
                {
                    neighborLabels.push_back(upPixel);
                }

                if (neighborLabels.empty())
                {
                    labelSet.push_back(++label);
                    data_curRow[j] = label;
                    labelSet[label] = label;
                }
                else
                {
                    sort(neighborLabels.begin(), neighborLabels.end());
                    int smallestLabel = neighborLabels[0];
                    data_curRow[j] = smallestLabel;
                    for (size_t k = 1; k < neighborLabels.size(); k++)
                    {
                        int tempLabel = neighborLabels[k];
                        int& oldSmallestLabel = labelSet[tempLabel];
                        if (oldSmallestLabel > smallestLabel)
                        {
                            labelSet[oldSmallestLabel] = smallestLabel;
                            oldSmallestLabel = smallestLabel;
                        }
                        else if (oldSmallestLabel < smallestLabel)
                        {
                            labelSet[smallestLabel] = oldSmallestLabel;
                        }
                    }
                }
            }
        }
    }
    for (size_t i = 2; i < labelSet.size(); i++)
    {
        int curLabel = labelSet[i];
        int preLabel = labelSet[curLabel];
        while (preLabel != curLabel)
        {
            curLabel = preLabel;
            preLabel = labelSet[preLabel];
        }
        labelSet[i] = curLabel;
    }
    for (int i = 0; i < rows; i++)
    {
        int* data = dimg.ptr<int>(i);
        for (int j = 0; j < cols; j++)
        {
            int& pixelLabel = data[j];
            pixelLabel = labelSet[pixelLabel];
        }
    }
}

Scalar RanColor()
{
    uchar r = 255 * (rand() / (1.0 + RAND_MAX));
    uchar g = 255 * (rand() / (1.0 + RAND_MAX));
    uchar b = 255 * (rand() / (1.0 + RAND_MAX));
    return Scalar(b, g, r);
}


void AddColor(const Mat& simg, Mat& dimg)
{
    if (simg.empty() ||
        simg.type() != CV_32SC1)
    {
        return;
    }

    map<int, Scalar> colors;

    int rows = simg.rows;
    int cols = simg.cols;

    dimg.release();
    dimg.create(rows, cols, CV_8UC3);
    dimg = Scalar::all(0);

    for (int i = 0; i < rows; i++)
    {
        const int* data_src = (int*)simg.ptr<int>(i);
        uchar* data_dst = dimg.ptr<uchar>(i);
        for (int j = 0; j < cols; j++)
        {
            int pixelValue = data_src[j];
            if (pixelValue > 1)
            {
                if (colors.count(pixelValue) <= 0)
                {
                    colors[pixelValue] = RanColor();
                }
                Scalar color = colors[pixelValue];
                *data_dst++ = color[0];
                *data_dst++ = color[1];
                *data_dst++ = color[2];
            }
            else
            {
                data_dst++;
                data_dst++;
                data_dst++;
            }
        }
    }
}


int main()
{
    Mat img = imread("head.jpg",0);
    Mat temp;
    img.copyTo(temp);
    threshold(img, temp, 50, 1, CV_THRESH_BINARY_INV);
    Mat labelImg;
    pass(temp, labelImg);

    Mat colorLabelImg;
    AddColor(labelImg, colorLabelImg);
    imshow("连通前", img);
    imshow("连通后", colorLabelImg);
    waitKey(0);

    return 0;
}

注意:运行前需要配置好opencv

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值