实验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