#include
#include
#include
#include
#
using namespace cv;
using namespace std;
Mat moveLightDiff(Mat src, int radius)
{
Mat dst;
Mat srcclone = src.clone();
Mat mask = Mat::zeros(radius * 2, radius * 2, CV_8U);
circle(mask, Point(radius, radius), radius, Scalar(255), -1);
dilate(srcclone, srcclone, mask);
erode(srcclone, srcclone, mask);
dst = srcclone - src;
return dst;
}
Mat RegionGrow(Mat src, Point2i pt, int th)
{
Point2i ptGrowing;
int nGrowLable = 0;
int nSrcValue = 0;
int nCurValue = 0;
int num = 0;
bool flag = true;
Mat matDst = Mat::zeros(src.size(), CV_8UC1);
Mat temp = Mat::zeros(src.size(), CV_8UC1);
int DIR[8][2] = { { -1, -1 },{ 0, -1 },{ 1, -1 },{ 1, 0 },{ 1, 1 },{ 0, 1 },{ -1, 1 },{ -1, 0 } };
vector<Point2i> vcGrowPt;
vcGrowPt.push_back(pt);
matDst.at<uchar>(pt.y, pt.x) = 255;
nSrcValue = src.at<uchar>(pt.y, pt.x);
while (!vcGrowPt.empty() && flag)
{
pt = vcGrowPt.back();
vcGrowPt.pop_back();
for (int i = 0; i<9; ++i)
{
ptGrowing.x = pt.x + DIR[i][0];
ptGrowing.y = pt.y + DIR[i][1];
if (ptGrowing.x < 0 || ptGrowing.y < 0 || ptGrowing.x >(src.cols - 1) || (ptGrowing.y > src.rows - 1))
continue;
nGrowLable = matDst.at<uchar>(ptGrowing.y, ptGrowing.x);
if (nGrowLable == 0)
{
nCurValue = src.at<uchar>(ptGrowing.y, ptGrowing.x);
if (abs(nSrcValue - nCurValue) < th)
{
matDst.at<uchar>(ptGrowing.y, ptGrowing.x) = 255;
vcGrowPt.push_back(ptGrowing);
num++;
if (num > 500)
{
flag = false;
break;
}
}
}
}
}
cout << num << endl;
if (num > 300)
{
return temp.clone();
}
else
{
return matDst.clone();
}
}
int main()
{
Mat src = imread("1-1.jpg");
Mat src_hsv;
cvtColor(src, src_hsv, COLOR_BGR2HSV);
Mat src_h, src_binary;
Mat src_gray;
cvtColor(src, src_gray, COLOR_BGR2GRAY);
int height, width;
height = src_gray.rows;
width = src_gray.cols;
vector<Mat> rgb_planes;
split(src_hsv, rgb_planes);
src_h = rgb_planes[0];
int r = (height < width ? height : width)/ 2 ;
Mat src_open, src_guass;
Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(13, 13), Point(-1, -1));
morphologyEx(src_gray, src_open, CV_MOP_OPEN, kernel);
GaussianBlur(src_open, src_guass, Size(5, 5), 3);
morphologyEx(src_guass, src_h, CV_MOP_BLACKHAT, kernel);
namedWindow("src_open", WINDOW_NORMAL);
imshow("src_open", src_open);
namedWindow("src_h", WINDOW_NORMAL);
imshow("src_h", src_h);
float hist[256] = {0};
for (int i = 0; i < src_gray.rows; i++)
{
for (int j = 0; j < src_gray.cols; j++)
{
int val = src_gray.at<uchar>(i, j);
if (val > 0)
{
hist[val]++;
}
}
}
Mat imgn = Mat::zeros(height, width, CV_32FC1);
int w = 3;
for (int i = w; i < height - w; i++)
{
for (int j = w; j < width - w; j++)
{
float histm[256] = { 0 };
for (int p = i - w; p < i+ w +1; p++)
{
for (int q = j - w; q < j + w+1; q++)
{
int val = src_h.at<uchar>(p, q);
histm[val]++;
}
}
float hist_prob[256] = { 0 };
float hist_sum = accumulate(histm, histm + 256, 0);
for (int k = 0; k < 256; k++)
{
hist_prob[k] = float(histm[k]) / float(hist_sum);
}
double entropy = 0;
for (int kk = 0; kk < 256; kk++)
{
if (hist_prob[kk] != 0)
{
entropy = entropy + hist_prob[kk] * log(1 / hist_prob[kk]);
}
}
imgn.at<float>(i, j) = entropy;
}
}
double minv, maxv;
Point pt_min, pt_max;
minMaxLoc(imgn, &minv, &maxv, &pt_min, &pt_max);
Mat imgn1 = Mat::zeros(height, width, CV_8UC1);;
for (int i = 0; i < imgn.rows; i++)
{
for (int j = 0; j < imgn.cols; j++)
{
float value = imgn.at<float>(i, j);
imgn1.at<uchar>(i, j) = round(255 * double(value - minv) / double(maxv - minv));
}
}
namedWindow("src_en", WINDOW_NORMAL);
imshow("src_en", imgn1);
threshold(imgn1, src_binary, 150, 255, THRESH_BINARY );
namedWindow("src_binary", WINDOW_NORMAL);
imshow("src_binary", src_binary);
vector<vector<Point>> bin_contours;
vector<Vec4i> bin_hireachy;
findContours(src_binary, bin_contours, bin_hireachy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE, Point());
vector<Point2f> mc;
for (int i = 0; i < bin_contours.size(); i++)
{
double area1 = contourArea(bin_contours[i]);
if (area1 > 4)
{
RotatedRect rect = minAreaRect(bin_contours[i]);
double x0, y0;
x0 = rect.center.x;
y0 = rect.center.y;
mc.push_back(rect.center);
}
}
for (int i = 0; i < mc.size(); i++)
{
cout << mc[i].x <<" " << mc[i].y<< endl;
}
int th = 40;
Mat dst;
Mat res = Mat::zeros(src_gray.size(), CV_8UC1);
for (int i = 0; i < mc.size(); i++)
{
Point2f pt = mc[i];
dst = RegionGrow(src_gray, pt, th);
bitwise_or(res, dst, res);
}
namedWindow("src_res", WINDOW_NORMAL);
imshow("src_res", res);
vector<vector<Point>> contours;
vector<Vec4i> hireachy;
findContours(res, contours, hireachy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE, Point());
vector<Point2f>center(contours.size());
vector<float>radius(contours.size());
for (int i = 0; i < contours.size(); i++)
{
minEnclosingCircle(contours[i], center[i], radius[i]);
}
for (int i = 0; i < contours.size(); i++)
{
circle(src, center[i], (int)radius[i], Scalar(0, 0, 255), 1, 8, 0);
cout << radius[i] << endl;
char diameter[20];
sprintf_s(diameter, "%d", 2 * (int)radius[i]);
cv::Point origin;
origin.x = center[i].x + 3;
origin.y = center[i].y - 3;
putText(src, diameter, origin, CV_FONT_HERSHEY_SCRIPT_SIMPLEX, 0.55, Scalar(0, 255, 0));
}
namedWindow("src_contours", WINDOW_NORMAL);
imshow("src_contours", src);
Mat result = Mat::zeros(src.size(), CV_8UC3);
waitKey(0);
system("pause");
return 0;
}
#include
#include
#include
#include
using namespace std;
using namespace cv;
void initfcm(int cluster_n, int data_n, cv::OutputArray U)
{
Mat U_temp(cluster_n, data_n, CV_32F);
randu(U_temp, Scalar::all(0), Scalar::all(1));
Mat U1, U2;
U1 = Mat::zeros(1, data_n, CV_32FC1);
reduce(U_temp, U1, 0, CV_REDUCE_SUM);
repeat(U1, cluster_n, 1, U2);
U_temp = U_temp.mul(1 / U2);
U_temp.copyTo(U);
}
void stepfcm(cv::InputArray data, cv::InputArray U, int cluster_n, int expo, double *obj_fcn_one, cv::OutputArray center, cv::OutputArray U_new)
{
Mat temp, temp1;
Mat A = Mat::ones(U.getMat().rows, U.getMat().cols, CV_32FC1);
Mat temp2;
absdiff(A, U, temp2);
float alpha = 0.85;
int pp = U.getMat().cols;
Mat temp3;
pow(U.getMat(), alpha, temp3);
absdiff(A, temp3, temp3);
temp3 = temp3.mul(1 / alpha);
Mat Ut;
absdiff(temp2, temp3, Ut);
Mat temp4;
reduce(Ut, temp4, 1, CV_REDUCE_SUM);
Mat pai = temp4.mul(1 / pp);
Mat obj;
Mat temp5;
temp5 = 1 - pai;
exp(temp5, temp5);
obj = pai.mul(temp5);
Scalar objs = sum(obj);
Mat Ud;
add(U.getMat(), Ut, Ud);
Mat nf, mf;
pow(U.getMat(), expo, mf);
Ud.copyTo(nf);
Mat data_trans;
transpose(data.getMat(), data_trans);
reduce(mf, temp, 1, CV_REDUCE_SUM);
Mat d = Mat::zeros(U.getMat().rows, U.getMat().cols, CV_32FC1);
for (int i = 0; i < d.rows; i++)
{
data_trans.copyTo(d.row(i));
}
Mat divisor = mf.mul(d);
reduce(divisor, temp1, 1, CV_REDUCE_SUM);
Mat result = temp1.mul(1/temp);
result.copyTo(center);
Mat dist = Mat::zeros(result.rows, data.getMat().rows, CV_32F);
for (int k = 0; k < result.rows; k++)
{
Mat a = Mat::ones(data.getMat().rows, 1, CV_32F) * result(Range(k, k + 1), Range::all());
Mat b = data.getMat();
Mat c;
b.convertTo(c, CV_32F, 1, 0);
Mat temp;
absdiff(a, c, temp);
transpose(temp, temp);
dist(Range(k, k + 1), Range::all()) = dist(Range(k, k + 1), Range::all()) + temp;
}
*obj_fcn_one = sum(dist.mul(dist).mul(mf))[0] + objs[0];
Mat tmp;
pow(dist, (-2 / (expo - 1)), tmp);
Mat Tmp;
reduce(tmp, Tmp, 0, CV_REDUCE_SUM);
Mat Unew = tmp.mul(1 / ((Mat::ones(cluster_n, 1, CV_32F)) * Tmp));
Unew.copyTo(U_new);
}
void ClustFCM(cv::InputArray image, cv::OutputArray U, cv::OutputArray obj_fcn, cv::OutputArray center, int cluster_n, float * option)
{
Mat data = image.getMat();
double data_n = data.rows;
int in_n = data.cols;
int expo = option[0];
int max_iter = option[1];
float min_impro = option[2];
int display = option[3];
initfcm(cluster_n, data_n, U);
cv::Mat U_new;
Mat obj_fcn_begin = Mat::zeros(max_iter, 1, CV_32F);
double obj_fcn_ones;
int iter_n;
for (int i = 1; i <= max_iter; i++)
{
stepfcm(data, U, cluster_n, expo, &obj_fcn_ones, center, U);
obj_fcn_begin.at<float>(i - 1, 0) = obj_fcn_ones;
if (display == 1)
{
cout << "第 迭代次数:" << i << "目标函数值:" << obj_fcn_ones << endl;
}
if (i > 1)
{
if (abs(obj_fcn_begin.at<float>(i - 1, 0) - obj_fcn_begin.at<float>(i - 2, 0))< min_impro)
{
iter_n = i;
break;
}
}
}
Mat obj_fcn_end = obj_fcn_begin(Range(0, iter_n), Range::all());
obj_fcn_end.copyTo(obj_fcn);
}
void image_segmentation(cv::Mat img, int cluster_n, float * option, cv::Mat &result)
{
int m = img.rows;
int n = img.cols;
int num = m * n;
Mat imgn = img.reshape(0, num);
cv::InputArray ptr = imgn;
cv::Mat U;
cv::Mat obj_fcn;
cv::Mat center;
ClustFCM(ptr, U, obj_fcn, center, cluster_n, option);
Mat maxU;
reduce(U, maxU, 0, CV_REDUCE_MAX);
Mat_<double> temp;
Mat center_sort;
center.copyTo(center_sort);
for (int i = 0; i < center.rows; i++)
{
for (int j = i + 1; j < center.rows; j++)
{
if (center_sort.at<float>(i, 0) > center_sort.at<float>(j, 0))
{
float tmp = center_sort.at<float>(i, 0);
center_sort.at<float>(i, 0) = center_sort.at<float>(j, 0);
center_sort.at<float>(j, 0) = tmp;
}
}
}
result = Mat::zeros(1, num, CV_32F);
float* data = result.ptr<float>(0);
int grays = 0;
for (int i = 0; i < cluster_n; i++)
{
Mat cla = U.row(i);
int id = 0;
for (int k = 0; k < center.rows; k++)
{
if (center_sort.at<float>(k, 0) == center.at<float>(i, 0))
{
id = k;
break;
}
}
if (id == 0)
{
grays = 0;
}
else if (id == cluster_n - 1)
{
grays = 255;
}
else
{
grays = floor(255 * id / (cluster_n - 1));
}
for (int j = 0; j < cla.cols; j++)
{
float x = U.at<float>(i, j);
float y = maxU.at<float>(0, j);
if (x == y)
{
data[j] = grays;
}
}
}
result = result.reshape(0, m);
}
int main()
{
Mat src = imread("24.jpg");
Mat img;
cvtColor(src, img, CV_BGR2GRAY);
int thresh_1 = 0.5;
int thresh_2 = 0.1;
int height = img.rows;
int width = img.cols;
int k_size = max(height, width);
Mat kernel = getStructuringElement(MORPH_RECT, Size(k_size, k_size));
morphologyEx(img, img, MORPH_TOPHAT, kernel);
namedWindow("2", 0);
imshow("2", img);
int cluster_n = 4;
float option[4] = { 2, 500, 1e-5, 1 };
Mat result;
image_segmentation(img, cluster_n, option, result);
namedWindow("3", 0);
imshow("3", result);
Mat bin_img;
threshold(result, bin_img, 128, 255, THRESH_BINARY);
cv::namedWindow("binary_img", 0);
cv::imshow("binary_img", bin_img);
imwrite("bin.jpg", bin_img);
Mat bi_img;
bin_img.convertTo(bi_img, CV_8U);
std::vector<std::vector<cv::Point>> contours;
std::vector<cv::Vec4i> hierarchy;
findContours(bi_img, contours, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE, cv::Point());
std::vector<cv::RotatedRect> box(contours.size());
vector<Rect> boundRect(contours.size());
cv::Point2f rect[4];
float center_x, center_y;
std::vector<cv::Point2f> pts_src;
int maxW = 0;
int maxH = 0;
for (int i = 0; i < contours.size(); i++)
{
cv::drawContours(src, contours, i, cv::Scalar(255, 0, 0), 1, 8, hierarchy);
box[i] = minAreaRect(Mat(contours[i]));
boundRect[i] = boundingRect(Mat(contours[i]));
if (boundRect[i].width > maxW)
{
maxW = boundRect[i].width;
}
if (boundRect[i].height > maxH)
{
maxH = boundRect[i].height;
}
rectangle(src, Point(boundRect[i].x, boundRect[i].y), Point(boundRect[i].x + boundRect[i].width, boundRect[i].y + boundRect[i].height), Scalar(0, 255, 0), 2, 8);
}
cv::namedWindow("contour_img", 0);
cv::imshow("contour_img", src);
Mat bin;
convertScaleAbs(bin_img, bin, 1.0 / 255);
double area = sum(bin)[0];
cout << area << endl;
float rate = area / (height * width);
if (rate > thresh_1)
{
cout << "不合格品" << endl;
}
if ((abs(maxW - width) < 5 || abs(maxH - height) < 5) && rate > thresh_2)
{
cout << "不合格品" << endl;
}
waitKey(0);
system("pause");
return 0;
}