细胞识别Region labeling and counting

#include"cv.h"
#include "bmpproperty.h"
#include <iostream>
#include<opencv2\opencv.hpp>
#include<math.h>
using namespace std;
using namespace cv;
void main(){
	Mat M = imread("dip2gray.jpg");
	Mat grayim(M.rows, M.cols, CV_8UC1);
	int count = 1; int c2 = count;
	for (int i = 0; i < M.rows; ++i)
	{
		for (int j = 0; j < M.cols; ++j){
			grayim.at<uchar>(i, j) = M.at<Vec3b>(i, j)[1];
			if (grayim.at<uchar>(i, j) < 66)
			{
				grayim.at<uchar>(i, j) = 0;
			}
			else grayim.at<uchar>(i, j) = 1;
		}
	}//二值化
	Mat I3(grayim.rows-2, grayim.cols-5, CV_8UC1);
	for (int i2 = 1; i2 < M.rows - 2; ++i2){
		for (int j2 = 3; j2 < M.cols - 3; ++j2){
			I3.at<uchar>(i2, j2 - 2) = grayim.at<uchar>(i2, j2);
		}
	}
	//去边框
	Mat label(I3.rows, I3.cols, CV_8UC1);
	for (int m = 1; m < I3.rows; ++m){
		for (int n = 1; n < I3.cols; ++n){
			label.at<uchar>(m, n) = 0;
		}
	}
	int vl[200]; int counter1[200];
	for (int m = 1; m < 200; ++m){
		vl[m] = 0; counter1[m] = 0;
	}
	int vl0; int p = 1;
	int m = 1;
	for (int n = 1; n < I3.cols; ++n){
		if (I3.at<uchar>(m, n) == 0){
			if (I3.at<uchar>(m, n - 1) == 1){
				count = count + 1;
				label.at<uchar>(m, n) = count;
			}
			if (I3.at<uchar>(m, n - 1) == 0){
				label.at<uchar>(m, n) = label.at<uchar>(m, n - 1);
			}
		}
	}
	for (int m = 2; m < I3.rows ; ++m){
		for (int n = 1; n < I3.cols ; ++n){
			if (I3.at<uchar>(m, n) == 0){
				if (I3.at<uchar>(m - 1, n) == 1 && I3.at<uchar>(m, n - 1) == 1){//case1
					count = count + 1;
					label.at<uchar>(m, n) = count;
				}
				if (I3.at<uchar>(m - 1, n) == 0 && I3.at<uchar>(m, n - 1) == 1){//case2
					label.at<uchar>(m, n) = label.at<uchar>(m - 1, n);
				}
				if (I3.at<uchar>(m - 1, n) == 1 && I3.at<uchar>(m, n - 1) == 0){//case3
					label.at<uchar>(m, n) = label.at<uchar>(m, n - 1);
				}
				if (I3.at<uchar>(m - 1, n) == 0 && I3.at<uchar>(m, n - 1) == 0){//case4
					label.at<uchar>(m, n) = label.at<uchar>(m, n - 1);
					if (label.at<uchar>(m, n - 1) != label.at<uchar>(m - 1, n)){
						if (vl[label.at<uchar>(m, n)] == 0){
							if (vl[label.at<uchar>(m - 1, n)] == 0){
								vl[label.at<uchar>(m, n)] = label.at<uchar>(m - 1, n);
							}
							else
								vl[label.at<uchar>(m, n)] = vl[label.at<uchar>(m - 1, n)];
						}
						else{
							if (vl[label.at<uchar>(m - 1, n)] == 0){
								vl[label.at<uchar>(m - 1, n)] = vl[label.at<uchar>(m, n)];
							}
							else{
								vl0 = vl[label.at<uchar>(m - 1, n)];
								for (p = 1; p <count; ++p){
									if (vl[p] == vl0)
										vl[p] = vl[label.at<uchar>(m, n)];
								}
							}
						}
					}
				}
			}
		}
	}imshow("test", label); waitKey(0);
	for (int m = 1; m < I3.rows; ++m){
		for (int n = 1; n < I3.cols; ++n){
			if (label.at<uchar>(m, n) != 0 && vl[label.at<uchar>(m, n)] != 0){
				label.at<uchar>(m, n) = vl[label.at<uchar>(m, n)];
			}
			else 
			if (label.at<uchar>(m, n) != 0 && vl[label.at<uchar>(m, n)] == 0){
				vl[label.at<uchar>(m, n)] = label.at<uchar>(m, n);
			}
			else	label.at<uchar>(m, n) = 0;
		}
	}
	//标记完毕
	int vl2[200];  int c1 = 0; int counter[200];
	for (int m = 1; m < 200; ++m){
		vl2[m] = 0; counter[m] = 0;
	}
	for (int m = 1; m < I3.rows; ++m){
		for (int n = 1; n < I3.cols; ++n){
			if (label.at<uchar>(m, n)){
				counter[label.at<uchar>(m, n) + 1] = counter[label.at<uchar>(m, n) + 1] + 1;
			}
		}
	}
	for (int m = 1; m < I3.rows; ++m){
		for (int n = 1; n < I3.cols; ++n){
			if (I3.at<uchar>(m, n) == 0){
				if ((counter[label.at<uchar>(m, n) + 1]) < 3){//滤除噪声
					I3.at<uchar>(m, n) = 1;
				}
			}
		}
	}
	//对滤波后的图像赋标志值
	Mat label1(I3.rows, I3.cols, CV_8UC1);
	for (int m = 1; m < I3.rows; ++m){
		for (int n = 1; n < I3.cols; ++n){
			if (I3.at<uchar>(m, n) == 0 && label.at<uchar>(m, n) != 0)
				label1.at<uchar>(m, n) = label.at<uchar>(m, n);
			else label1.at<uchar>(m, n) = 0;
		}
	}
	//计数函数
	int v1 = 1;
	for (int m = 1; m < I3.rows; ++m){
		for (int n = 1; n < I3.cols; ++n){
			if (label1.at<uchar>(m, n) != 0){
				c1 = 0;
				for (int v2 = 1; v2 <= v1; v2++){
					if (label1.at<uchar>(m, n) != vl2[v2]){
						c1 = c1 + 1;
					}
				}
				if (v1 == c1){
					vl2[v1] = label1.at<uchar>(m, n);
					v1 = v1 + 1;
				}
			}
		}
	}
	//上色函数
	int num = v1 - 1;
	Mat label2(I3.rows, I3.cols, CV_8UC3);
	for (int m = 1; m < I3.rows; ++m){
		for (int n = 1; n < I3.cols; ++n){
			if (label1.at<uchar>(m, n) != 0){
				label2.at<Vec3b>(m, n)[0] = floor(label1.at<uchar>(m, n)*1.4);
				label2.at<Vec3b>(m, n)[1] = floor(abs(76 - label1.at<uchar>(m, n))*3.2);
				label2.at<Vec3b>(m, n)[2] = floor((192 - label1.at<uchar>(m, n))*1.5);
			}
			else{
				label2.at<Vec3b>(m, n)[0] = 153;
				label2.at<Vec3b>(m, n)[1] = 248;
				label2.at<Vec3b>(m, n)[2] = 127;
			}
		}
	}
	//滤波边框加粗
	Mat I4(I3.rows, I3.cols, CV_8UC1);
	for (int m = 1; m < I3.rows; ++m){
		for (int n = 1; n < I3.cols; ++n){
			I4.at<uchar>(m, n) = I3.at<uchar>(m, n);
		}
	}
	for (int m = 1; m < I3.rows - 1; ++m){
		for (int n = 1; n < I3.cols - 1; ++n){
			if (I3.at<uchar>(m + 1, n) == 0 || I3.at<uchar>(m, n + 1) == 0){
				I4.at<uchar>(m , n) = 0;
			}
		}
	}
	imshow("grayim", grayim * 255);
	imshow("cut", I3 * 255);
	imshow("color", label2);
	imshow("boundary", I4*255);
	cout <<"Number="<< num<<endl;
	cout << "Counter=" << endl;
	for (int i = 1; i < 200; ++i){
		cout <<  counter[i] <<" ";
	}
	waitKey(0);
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值