图像处理计数_图像处理计数matlab - CSDN
  • 通过二值分割+形态学处理+距离变换+形态学变换(具体问题具体分析)+连通区域计算 #include <opencv2/opencv.hpp> #include <iostream> using namespace std; using namespace cv; int main(int argc, ...
    1. 计算对象个数
      通过二值分割+形态学处理+距离变换+形态学变换(具体问题具体分析)+连通区域计算
    #include <opencv2/opencv.hpp>
    #include <iostream>
    
    using namespace std;
    using namespace cv;
    
    int main(int argc, char** argv)
    {
    	Mat src,temp,temp_mor,temp_dist,dst;
    	src = imread("../path.jpg",IMREAD_GRAYSCALE);
    	if (src.empty())
    	{
    		cout << "could not load image..." << endl;
    		return -1;
    	}
    
    	namedWindow("src", WINDOW_AUTOSIZE);
    	imshow("src", src);
    	//通过二值分割
    	threshold(src, temp, 0, 255, THRESH_BINARY | THRESH_TRIANGLE);
    	//imshow("Threshold", temp);
    	
    	//形态学处理
    	Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
    	dilate(temp, temp_mor, kernel, Point(-1, -1), 1);//膨胀
    	//imshow("MorphShape", temp_mor);
    	
    	//距离变换
    	bitwise_not(temp_mor, temp_mor);//取反,物体变白,背景变黑
    	distanceTransform(temp_mor, temp_dist, DIST_L2, 3);
    	normalize(temp_dist, temp_dist, 0, 0.9, NORM_MINMAX);
    	imshow("Distance", temp_dist);
    	
    	// 阈值化二值分割
    	Mat temp_dist_8u;
    	temp_dist.convertTo(temp_dist_8u, CV_8U);
    	//threshold(temp_dist_8u, temp_dist_8u, 0.5, 1, THRESH_BINARY);//使用阈值,再次二值化,得到标记
    	adaptiveThreshold(temp_dist_8u, temp_dist_8u, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY,81, 0);//使用自适应阈值,再次二值化,得到标记
    	//erode(temp_dist_8u, temp_dist_8u, kernel, Point(-1, -1), 1);
    	dilate(temp_dist_8u, temp_dist_8u, kernel, Point(-1, -1), 3);//形态学操作,分割各个连通区域
    
    	imshow("Dilate", temp_dist_8u);
    	
    	//连通区域计算
    	vector<vector<Point>> contours;
    	findContours(temp_dist_8u, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);//寻找(外部)轮廓
    	
    	dst = Mat::zeros(src.size(), CV_8UC3);
    	RNG rng;
    	for (size_t i = 0; i < contours.size(); i++)
    	{
    		//绘制轮廓
    		drawContours(dst, contours, static_cast<int>(i), Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)),-1, 8);
    	}
    	cout << "共有轮廓:" << contours.size() << endl;
    	imshow("Final", dst);
    
    	waitKey(0);
    	return 0;
    }
    

    src为:
    在这里插入图片描述
    输出结果为:
    在这里插入图片描述

    展开全文
  • 为探索水稻谷粒图像快速计数方法,修正或减少因谷粒粘连引起的误差,采用黑色平面结合机械振动分散谷粒并采集图像,利用Matlab软件对图像进行灰度处理、二值化处理、两步开运算及腐蚀运算等消除粘连,并对计数点标记和...

           为探索水稻谷粒图像快速计数方法,修正或减少因谷粒粘连引起的误差,采用黑色平面结合机械振动分散谷粒并采集图像,利用Matlab软件对图像进行灰度处理、二值化处理、两步开运算及腐蚀运算等消除粘连,并对计数点标记和计算.在灰度图上作开运算能有效修整谷粒边缘,腐蚀运算后谷粒中心与边缘亮暗对比更加鲜明,二值化后的图像初步分离效果好,在进一步开运算和腐蚀运算后,颗粒缩小,边界距离增大,解决了绝大部分粘连.对计数点标记后,非计数点更容易观察。

    clc;clear all;close all;set(0,'defaultfigurecolor','w')I=imread('123.png');x=rgb2gray(I);figure(1);subplot(3,2,1);imshow(I);title('原始图像');subplot(3,2,2);imshow(x);title('灰度图像'); thresh=graythresh(x);J1=imnoise(x,'gaussian',0,0.01);hood=3;K1=medfilt2(J1,[hood hood]);subplot(3,2,3);imshow(K1);title('高斯噪声的滤波效果');I2=im2bw(x,thresh);subplot(3,2,4);imshow(I2)title('二值图像');J=edge(I2,'canny');    K=imfill(J,'holes');  subplot(3,2,5);imshow(K);  SE=strel('disk',1);%用于膨胀腐蚀及开闭运算等操作的结构元素对象    L=imopen(K,SE);  %对图像实现开运算,开运算一般能平滑图像的轮廓,消弱狭窄的部分,去掉细的突出。subplot(3,2,6);imshow(L);  M=bwlabel(L,4);%联通域标记  [m,n]=size(M);  %矩阵M的大小 num=0;%谷物颗粒的个数   for i=1:m      for j=1:n          if M(i,j)>num%最大的label值即联通域的个数              num=M(i,j);          end      end  end  disp('谷物颗粒个数:');  disp(num);

    往期回顾>>>>>>

    【优化求解】模拟退火遗传实现带时间窗的车辆路径规划问题

    【优化算法】遗传算法求最短路径

    【优化问题】遗传算法求最值

    【基础教程】MATLAB导出高清晰图片

    【优化问题】基于栅格地图——遗传算法的机器人最优路径规划

     

    展开全文
  • 一位网友给我发了几张灰度图像,说是他们单位的工业相机拍摄的,画质非常的清楚,他们单位是农业科研单位,特别想知道种子的数量,他想知道的是每次工业相机拍摄种子图片中有多少颗粒种子,想到了用图像处理的办法...

    一位网友给我发了几张灰度图像,说是他们单位的工业相机拍摄的,画质非常的清楚,他们

    单位是农业科研单位,特别想知道种子的数量,他想知道的是每次工业相机拍摄种子图片中

    有多少颗粒种子,想到了用图像处理的办法解决他们的问题,看了他给我照片,以大米种子

    为例。实现了一个简单的算法流程,可以得到种子的数目。

    大致算法分为以下三个步骤:

    1.      将灰度图像二值化,二值化方法可以参考以前的文章,求取像素平均值,灰度直方图都

              可以

    2.      去掉二值化以后的图像中干扰噪声。

    3.      得到种子数目,用彩色标记出来。


    源图像如下:


    程序处理中间结果及最终效果如下:


    二值化处理参见以前的文章 - http://blog.csdn.net/jia20003/article/details/7392325

    大米计数与噪声块消去算法基于连通组件标记算法,源代码如下:

    1. package com.gloomyfish.rice.analysis;  
    2.   
    3. import java.awt.image.BufferedImage;  
    4. import java.util.ArrayList;  
    5. import java.util.Arrays;  
    6. import java.util.HashMap;  
    7.   
    8. import com.gloomyfish.face.detection.AbstractBufferedImageOp;  
    9. import com.gloomyfish.face.detection.FastConnectedComponentLabelAlg;  
    10.   
    11. public class FindRiceFilter extends AbstractBufferedImageOp {  
    12.       
    13.     private int sumRice;  
    14.       
    15.     public int getSumRice() {  
    16.         return this.sumRice;  
    17.     }  
    18.   
    19.     @Override  
    20.     public BufferedImage filter(BufferedImage src, BufferedImage dest) {  
    21.         int width = src.getWidth();  
    22.         int height = src.getHeight();  
    23.   
    24.         if ( dest == null )  
    25.             dest = createCompatibleDestImage( src, null );  
    26.   
    27.         int[] inPixels = new int[width*height];  
    28.         int[] outPixels = new int[width*height];  
    29.         getRGB(src, 00, width, height, inPixels );  
    30.           
    31.         FastConnectedComponentLabelAlg fccAlg = new FastConnectedComponentLabelAlg();  
    32.         fccAlg.setBgColor(0);  
    33.         int[] outData = fccAlg.doLabel(inPixels, width, height);  
    34.         // labels statistic  
    35.         HashMap<Integer, Integer> labelMap = new HashMap<Integer, Integer>();  
    36.         for(int d=0; d<outData.length; d++) {  
    37.             if(outData[d] != 0) {  
    38.                 if(labelMap.containsKey(outData[d])) {  
    39.                     Integer count = labelMap.get(outData[d]);  
    40.                     count+=1;  
    41.                     labelMap.put(outData[d], count);  
    42.                 } else {  
    43.                     labelMap.put(outData[d], 1);  
    44.                 }  
    45.             }  
    46.         }  
    47.           
    48.         // try to find the max connected component  
    49.         Integer[] keys = labelMap.keySet().toArray(new Integer[0]);  
    50.         Arrays.sort(keys);  
    51.         int threshold = 10;  
    52.         ArrayList<Integer> listKeys = new ArrayList<Integer>();  
    53.         for(Integer key : keys) {  
    54.             if(labelMap.get(key) <=threshold){  
    55.                 listKeys.add(key);  
    56.             }  
    57.             System.out.println( "Number of " + key + " = " + labelMap.get(key));  
    58.         }  
    59.         sumRice = keys.length - listKeys.size();  
    60.           
    61.         // calculate means of pixel    
    62.         int index = 0;      
    63.         for(int row=0; row<height; row++) {    
    64.             int ta = 0, tr = 0, tg = 0, tb = 0;    
    65.             for(int col=0; col<width; col++) {    
    66.                 index = row * width + col;    
    67.                 ta = (inPixels[index] >> 24) & 0xff;    
    68.                 tr = (inPixels[index] >> 16) & 0xff;    
    69.                 tg = (inPixels[index] >> 8) & 0xff;    
    70.                 tb = inPixels[index] & 0xff;  
    71.                 if(outData[index] != 0 && validRice(outData[index], listKeys)) {  
    72.                     tr = tg = tb = 255;  
    73.                 } else {  
    74.                     tr = tg = tb = 0;  
    75.                 }  
    76.                 outPixels[index] = (ta << 24) | (tr << 16) | (tg << 8) | tb;  
    77.             }  
    78.         }  
    79.         setRGB( dest, 00, width, height, outPixels );  
    80.         return dest;  
    81.     }  
    82.   
    83.     private boolean validRice(int i, ArrayList<Integer> listKeys) {  
    84.         for(Integer key : listKeys) {  
    85.             if(key == i) {  
    86.                 return false;  
    87.             }  
    88.         }  
    89.         return true;  
    90.     }  
    91.   
    92. }  
    大米着色处理很简单,只是简单RGB固定着色,源码如下:

    1. package com.gloomyfish.rice.analysis;  
    2.   
    3. import java.awt.image.BufferedImage;  
    4.   
    5. import com.gloomyfish.face.detection.AbstractBufferedImageOp;  
    6.   
    7. public class ColorfulRiceFilter extends AbstractBufferedImageOp {  
    8.   
    9.     @Override  
    10.     public BufferedImage filter(BufferedImage src, BufferedImage dest) {  
    11.         int width = src.getWidth();  
    12.         int height = src.getHeight();  
    13.   
    14.         if ( dest == null )  
    15.             dest = createCompatibleDestImage( src, null );  
    16.   
    17.         int[] inPixels = new int[width*height];  
    18.         int[] outPixels = new int[width*height];  
    19.         getRGB(src, 00, width, height, inPixels );  
    20.           
    21.         int index = 0, srcrgb;  
    22.         for(int row=0; row<height; row++) {    
    23.             int ta = 255, tr = 0, tg = 0, tb = 0;    
    24.             for(int col=0; col<width; col++) {   
    25.                 index = row * width + col;    
    26. //                ta = (inPixels[index] >> 24) & 0xff;    
    27. //                tr = (inPixels[index] >> 16) & 0xff;    
    28. //                tg = (inPixels[index] >> 8) & 0xff;    
    29. //                tb = inPixels[index] & 0xff;    
    30.                 srcrgb = inPixels[index] & 0x000000ff;  
    31.                 if(srcrgb > 0 && row < 140) {  
    32.                     tr = 0;  
    33.                     tg = 255;  
    34.                     tb = 0;  
    35.                 } else if(srcrgb > 0 && row >= 140 && row <=280) {  
    36.                     tr = 0;  
    37.                     tg = 0;  
    38.                     tb = 255;  
    39.                 } else if(srcrgb > 0 && row >=280) {  
    40.                     tr = 255;  
    41.                     tg = 0;  
    42.                     tb = 0;  
    43.                 }  
    44.                 else {  
    45.                     tr = tg = tb = 0;  
    46.                 }  
    47.                 outPixels[index] = (ta << 24) | (tr << 16) | (tg << 8) | tb;  
    48.             }  
    49.         }  
    50.         setRGB( dest, 00, width, height, outPixels );  
    51.         return dest;  
    52.     }  
    53. }  
    测试程序UI代码如下:

    1. package com.gloomyfish.rice.analysis;  
    2.   
    3. import java.awt.BorderLayout;  
    4. import java.awt.Color;  
    5. import java.awt.Dimension;  
    6. import java.awt.FlowLayout;  
    7. import java.awt.Graphics;  
    8. import java.awt.Graphics2D;  
    9. import java.awt.Image;  
    10. import java.awt.MediaTracker;  
    11. import java.awt.event.ActionEvent;  
    12. import java.awt.event.ActionListener;  
    13. import java.awt.image.BufferedImage;  
    14. import java.io.File;  
    15. import java.io.IOException;  
    16.   
    17. import javax.imageio.ImageIO;  
    18. import javax.swing.JButton;  
    19. import javax.swing.JComponent;  
    20. import javax.swing.JFileChooser;  
    21. import javax.swing.JFrame;  
    22. import javax.swing.JPanel;  
    23.   
    24. public class MainFrame extends JComponent implements ActionListener {  
    25.     /** 
    26.      *  
    27.      */  
    28.     private static final long serialVersionUID = 1518574788794973574L;  
    29.     public final static String BROWSE_CMD = "Browse...";  
    30.     public final static String NOISE_CMD = "Remove Noise";  
    31.     public final static String FUN_CMD = "Colorful Rice";  
    32.       
    33.     private BufferedImage rawImg;  
    34.     private BufferedImage resultImage;  
    35.     private MediaTracker tracker;  
    36.     private Dimension mySize;  
    37.       
    38.     // JButtons  
    39.     private JButton browseBtn;  
    40.     private JButton noiseBtn;  
    41.     private JButton colorfulBtn;  
    42.   
    43.     // rice number....  
    44.     private int riceNum = -1;  
    45.       
    46.       
    47.     public MainFrame() {  
    48.         JPanel btnPanel = new JPanel();  
    49.         btnPanel.setLayout(new FlowLayout(FlowLayout.LEFT));  
    50.         browseBtn = new JButton("Browse...");  
    51.         noiseBtn = new JButton("Remove Noise");  
    52.         colorfulBtn = new JButton("Colorful Rice");  
    53.           
    54.         browseBtn.setToolTipText("Please select image file...");  
    55.         noiseBtn.setToolTipText("find connected region and draw red rectangle");  
    56.         colorfulBtn.setToolTipText("Remove the minor noise region pixels...");  
    57.           
    58.         // buttons  
    59.         btnPanel.add(browseBtn);  
    60.         btnPanel.add(noiseBtn);  
    61.         btnPanel.add(colorfulBtn);  
    62.           
    63.         // setup listener...  
    64.         browseBtn.addActionListener(this);  
    65.         noiseBtn.addActionListener(this);  
    66.         colorfulBtn.addActionListener(this);  
    67.           
    68.         browseBtn.setEnabled(true);  
    69.         noiseBtn.setEnabled(true);  
    70.         colorfulBtn.setEnabled(true);  
    71.           
    72. //      minX = minY =  10000;  
    73. //      maxX = maxY = -1;  
    74.           
    75.         mySize = new Dimension(500300);  
    76.         JFrame demoUI = new JFrame("Rice Detection Demo");  
    77.         demoUI.getContentPane().setLayout(new BorderLayout());  
    78.         demoUI.getContentPane().add(this, BorderLayout.CENTER);  
    79.         demoUI.getContentPane().add(btnPanel, BorderLayout.SOUTH);  
    80.         demoUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
    81.         demoUI.pack();  
    82.         demoUI.setVisible(true);  
    83.     }  
    84.       
    85.     public void paint(Graphics g) {  
    86.         Graphics2D g2 = (Graphics2D) g;  
    87.         if(rawImg != null) {  
    88.             Image scaledImage = rawImg.getScaledInstance(200200, Image.SCALE_FAST);  
    89.             g2.drawImage(scaledImage, 00200200null);  
    90.         }  
    91.         if(resultImage != null) {  
    92.             Image scaledImage = resultImage.getScaledInstance(200200, Image.SCALE_FAST);  
    93.             g2.drawImage(scaledImage, 2100200200null);  
    94.         }  
    95.           
    96.         g2.setPaint(Color.RED);  
    97.         if(riceNum > 0) {  
    98.             g2.drawString("Number of Rice : " + riceNum, 100300);  
    99.         } else {  
    100.             g2.drawString("Number of Rice : Unknown"100300);  
    101.         }  
    102.     }  
    103.     public Dimension getPreferredSize() {  
    104.         return mySize;  
    105.     }  
    106.       
    107.     public Dimension getMinimumSize() {  
    108.         return mySize;  
    109.     }  
    110.       
    111.     public Dimension getMaximumSize() {  
    112.         return mySize;  
    113.     }  
    114.       
    115.     public static void main(String[] args) {  
    116.         new MainFrame();  
    117.     }  
    118.       
    119.     @Override  
    120.     public void actionPerformed(ActionEvent e) {  
    121.         if(BROWSE_CMD.equals(e.getActionCommand())) {  
    122.             JFileChooser chooser = new JFileChooser();  
    123.             chooser.showOpenDialog(null);  
    124.             File f = chooser.getSelectedFile();  
    125.             BufferedImage bImage = null;  
    126.             if(f == nullreturn;  
    127.             try {  
    128.                 bImage = ImageIO.read(f);  
    129.                   
    130.             } catch (IOException e1) {  
    131.                 e1.printStackTrace();  
    132.             }  
    133.               
    134.             tracker = new MediaTracker(this);  
    135.             tracker.addImage(bImage, 1);  
    136.               
    137.             // blocked 10 seconds to load the image data  
    138.             try {  
    139.                 if (!tracker.waitForID(110000)) {  
    140.                     System.out.println("Load error.");  
    141.                     System.exit(1);  
    142.                 }// end if  
    143.             } catch (InterruptedException ine) {  
    144.                 ine.printStackTrace();  
    145.                 System.exit(1);  
    146.             } // end catch  
    147.             BinaryFilter bfilter = new BinaryFilter();  
    148.             rawImg = bfilter.filter(bImage, null);  
    149.             repaint();  
    150.         } else if(NOISE_CMD.equals(e.getActionCommand())) {  
    151.             FindRiceFilter frFilter = new FindRiceFilter();  
    152.             resultImage = frFilter.filter(rawImg, null);  
    153.             riceNum = frFilter.getSumRice();  
    154.             repaint();  
    155.         } else if(FUN_CMD.equals(e.getActionCommand())) {  
    156.             ColorfulRiceFilter cFilter = new ColorfulRiceFilter();  
    157.             resultImage = cFilter.filter(resultImage, null);  
    158.             repaint();  
    159.         } else {  
    160.             // do nothing...  
    161.         }  
    162.           
    163.     }  
    164. }  
    展开全文
  • 图像处理之简单综合实例(大米计数) 一位网友给我发了几张灰度图像,说是他们单位的工业相机拍摄的,画质非常的清楚,他们 单位是农业科研单位,特别想知道种子的数量,他想知道的是每次工业相机拍摄种子图片中 有...

    图像处理之简单综合实例(大米计数)

    一位网友给我发了几张灰度图像,说是他们单位的工业相机拍摄的,画质非常的清楚,他们

    单位是农业科研单位,特别想知道种子的数量,他想知道的是每次工业相机拍摄种子图片中

    有多少颗粒种子,想到了用图像处理的办法解决他们的问题,看了他给我照片,以大米种子

    为例。实现了一个简单的算法流程,可以得到种子的数目。

    大致算法分为以下三个步骤:

    1.将灰度图像二值化,二值化方法可以参考以前的文章,求取像素平均值,灰度直方图都

    可以

    2.去掉二值化以后的图像中干扰噪声。

    3.得到种子数目,用彩色标记出来。


    源图像如下:


    程序处理中间结果及最终效果如下:


    二值化处理参见以前的文章 -http://blog.csdn.net/jia20003/article/details/7392325

    大米计数与噪声块消去算法基于连通组件标记算法,源代码如下:

    package com.gloomyfish.rice.analysis;
    
    import java.awt.image.BufferedImage;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.HashMap;
    
    import com.gloomyfish.face.detection.AbstractBufferedImageOp;
    import com.gloomyfish.face.detection.FastConnectedComponentLabelAlg;
    
    public class FindRiceFilter extends AbstractBufferedImageOp {
    	
    	private int sumRice;
    	
    	public int getSumRice() {
    		return this.sumRice;
    	}
    
    	@Override
    	public BufferedImage filter(BufferedImage src, BufferedImage dest) {
    		int width = src.getWidth();
            int height = src.getHeight();
    
            if ( dest == null )
                dest = createCompatibleDestImage( src, null );
    
            int[] inPixels = new int[width*height];
            int[] outPixels = new int[width*height];
            getRGB(src, 0, 0, width, height, inPixels );
            
    		FastConnectedComponentLabelAlg fccAlg = new FastConnectedComponentLabelAlg();
    		fccAlg.setBgColor(0);
    		int[] outData = fccAlg.doLabel(inPixels, width, height);
    		// labels statistic
    		HashMap<Integer, Integer> labelMap = new HashMap<Integer, Integer>();
    		for(int d=0; d<outData.length; d++) {
    			if(outData[d] != 0) {
    				if(labelMap.containsKey(outData[d])) {
    					Integer count = labelMap.get(outData[d]);
    					count+=1;
    					labelMap.put(outData[d], count);
    				} else {
    					labelMap.put(outData[d], 1);
    				}
    			}
    		}
    		
    		// try to find the max connected component
    		Integer[] keys = labelMap.keySet().toArray(new Integer[0]);
    		Arrays.sort(keys);
    		int threshold = 10;
    		ArrayList<Integer> listKeys = new ArrayList<Integer>();
    		for(Integer key : keys) {
    			if(labelMap.get(key) <=threshold){
    				listKeys.add(key);
    			}
    			System.out.println( "Number of " + key + " = " + labelMap.get(key));
    		}
    		sumRice = keys.length - listKeys.size();
    		
            // calculate means of pixel  
            int index = 0;    
            for(int row=0; row<height; row++) {  
                int ta = 0, tr = 0, tg = 0, tb = 0;  
                for(int col=0; col<width; col++) {  
                    index = row * width + col;  
                    ta = (inPixels[index] >> 24) & 0xff;  
                    tr = (inPixels[index] >> 16) & 0xff;  
                    tg = (inPixels[index] >> 8) & 0xff;  
                    tb = inPixels[index] & 0xff;
                    if(outData[index] != 0 && validRice(outData[index], listKeys)) {
                    	tr = tg = tb = 255;
                    } else {
                    	tr = tg = tb = 0;
                    }
                    outPixels[index] = (ta << 24) | (tr << 16) | (tg << 8) | tb;
                }
            }
            setRGB( dest, 0, 0, width, height, outPixels );
            return dest;
    	}
    
    	private boolean validRice(int i, ArrayList<Integer> listKeys) {
    		for(Integer key : listKeys) {
    			if(key == i) {
    				return false;
    			}
    		}
    		return true;
    	}
    
    }
    
    大米着色处理很简单,只是简单RGB固定着色,源码如下:

    package com.gloomyfish.rice.analysis;
    
    import java.awt.image.BufferedImage;
    
    import com.gloomyfish.face.detection.AbstractBufferedImageOp;
    
    public class ColorfulRiceFilter extends AbstractBufferedImageOp {
    
    	@Override
    	public BufferedImage filter(BufferedImage src, BufferedImage dest) {
    		int width = src.getWidth();
            int height = src.getHeight();
    
            if ( dest == null )
                dest = createCompatibleDestImage( src, null );
    
            int[] inPixels = new int[width*height];
            int[] outPixels = new int[width*height];
            getRGB(src, 0, 0, width, height, inPixels );
            
            int index = 0, srcrgb;
            for(int row=0; row<height; row++) {  
                int ta = 255, tr = 0, tg = 0, tb = 0;  
                for(int col=0; col<width; col++) { 
                    index = row * width + col;  
    //                ta = (inPixels[index] >> 24) & 0xff;  
    //                tr = (inPixels[index] >> 16) & 0xff;  
    //                tg = (inPixels[index] >> 8) & 0xff;  
    //                tb = inPixels[index] & 0xff;  
                	srcrgb = inPixels[index] & 0x000000ff;
                	if(srcrgb > 0 && row < 140) {
                		tr = 0;
                		tg = 255;
                		tb = 0;
                	} else if(srcrgb > 0 && row >= 140 && row <=280) {
                		tr = 0;
                		tg = 0;
                		tb = 255;
                	} else if(srcrgb > 0 && row >=280) {
                		tr = 255;
                		tg = 0;
                		tb = 0;
                	}
                	else {
                		tr = tg = tb = 0;
                	}
                	outPixels[index] = (ta << 24) | (tr << 16) | (tg << 8) | tb;
                }
            }
            setRGB( dest, 0, 0, width, height, outPixels );
            return dest;
    	}
    }
    
    测试程序UI代码如下:

    package com.gloomyfish.rice.analysis;
    
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.FlowLayout;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Image;
    import java.awt.MediaTracker;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    
    import javax.imageio.ImageIO;
    import javax.swing.JButton;
    import javax.swing.JComponent;
    import javax.swing.JFileChooser;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    public class MainFrame extends JComponent implements ActionListener {
    	/**
    	 * 
    	 */
    	private static final long serialVersionUID = 1518574788794973574L;
    	public final static String BROWSE_CMD = "Browse...";
    	public final static String NOISE_CMD = "Remove Noise";
    	public final static String FUN_CMD = "Colorful Rice";
    	
    	private BufferedImage rawImg;
    	private BufferedImage resultImage;
    	private MediaTracker tracker;
    	private Dimension mySize;
    	
    	// JButtons
    	private JButton browseBtn;
    	private JButton noiseBtn;
    	private JButton colorfulBtn;
    
    	// rice number....
    	private int riceNum = -1;
    	
    	
    	public MainFrame() {
    		JPanel btnPanel = new JPanel();
    		btnPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
    		browseBtn = new JButton("Browse...");
    		noiseBtn = new JButton("Remove Noise");
    		colorfulBtn = new JButton("Colorful Rice");
    		
    		browseBtn.setToolTipText("Please select image file...");
    		noiseBtn.setToolTipText("find connected region and draw red rectangle");
    		colorfulBtn.setToolTipText("Remove the minor noise region pixels...");
    		
    		// buttons
    		btnPanel.add(browseBtn);
    		btnPanel.add(noiseBtn);
    		btnPanel.add(colorfulBtn);
    		
    		// setup listener...
    		browseBtn.addActionListener(this);
    		noiseBtn.addActionListener(this);
    		colorfulBtn.addActionListener(this);
    		
    		browseBtn.setEnabled(true);
    		noiseBtn.setEnabled(true);
    		colorfulBtn.setEnabled(true);
    		
    //		minX = minY =  10000;
    //		maxX = maxY = -1;
    		
    		mySize = new Dimension(500, 300);
    		JFrame demoUI = new JFrame("Rice Detection Demo");
    		demoUI.getContentPane().setLayout(new BorderLayout());
    		demoUI.getContentPane().add(this, BorderLayout.CENTER);
    		demoUI.getContentPane().add(btnPanel, BorderLayout.SOUTH);
    		demoUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		demoUI.pack();
    		demoUI.setVisible(true);
    	}
    	
    	public void paint(Graphics g) {
    		Graphics2D g2 = (Graphics2D) g;
    		if(rawImg != null) {
    			Image scaledImage = rawImg.getScaledInstance(200, 200, Image.SCALE_FAST);
    			g2.drawImage(scaledImage, 0, 0, 200, 200, null);
    		}
    		if(resultImage != null) {
    			Image scaledImage = resultImage.getScaledInstance(200, 200, Image.SCALE_FAST);
    			g2.drawImage(scaledImage, 210, 0, 200, 200, null);
    		}
    		
    		g2.setPaint(Color.RED);
    		if(riceNum > 0) {
    			g2.drawString("Number of Rice : " + riceNum, 100, 300);
    		} else {
    			g2.drawString("Number of Rice : Unknown", 100, 300);
    		}
    	}
    	public Dimension getPreferredSize() {
    		return mySize;
    	}
    	
    	public Dimension getMinimumSize() {
    		return mySize;
    	}
    	
    	public Dimension getMaximumSize() {
    		return mySize;
    	}
    	
    	public static void main(String[] args) {
    		new MainFrame();
    	}
    	
    	@Override
    	public void actionPerformed(ActionEvent e) {
    		if(BROWSE_CMD.equals(e.getActionCommand())) {
    			JFileChooser chooser = new JFileChooser();
    			chooser.showOpenDialog(null);
    			File f = chooser.getSelectedFile();
    			BufferedImage bImage = null;
    			if(f == null) return;
    			try {
    				bImage = ImageIO.read(f);
    				
    			} catch (IOException e1) {
    				e1.printStackTrace();
    			}
    			
    			tracker = new MediaTracker(this);
    			tracker.addImage(bImage, 1);
    			
    			// blocked 10 seconds to load the image data
    			try {
    				if (!tracker.waitForID(1, 10000)) {
    					System.out.println("Load error.");
    					System.exit(1);
    				}// end if
    			} catch (InterruptedException ine) {
    				ine.printStackTrace();
    				System.exit(1);
    			} // end catch
    			BinaryFilter bfilter = new BinaryFilter();
    			rawImg = bfilter.filter(bImage, null);
    			repaint();
    		} else if(NOISE_CMD.equals(e.getActionCommand())) {
    			FindRiceFilter frFilter = new FindRiceFilter();
    			resultImage = frFilter.filter(rawImg, null);
    			riceNum = frFilter.getSumRice();
    			repaint();
    		} else if(FUN_CMD.equals(e.getActionCommand())) {
    			ColorfulRiceFilter cFilter = new ColorfulRiceFilter();
    			resultImage = cFilter.filter(resultImage, null);
    			repaint();
    		} else {
    			// do nothing...
    		}
    		
    	}
    }
    
    关于连通组件标记算法,我实现一个优化过的快速版本,可以参见

    http://blog.csdn.net/jia20003/article/details/7596443



    展开全文
  • 图像处理_对象计数

    2018-11-16 19:56:35
    (1)二值分割 (2)形态学处理 (3)距离变换 (4)连通区域计算
  • 基于数字图像处理的小目标计数(二)

    千次阅读 热门讨论 2018-04-18 00:16:43
    存在接壤现象的细胞计数 因为前面(一)的中的图片每个波点之间间隔较小,这边的细胞图中存在多个目标接壤问题,所以怎样在存在接壤现象的细胞中准确数出个数是这里较前面不同的地方。 解决思路: 进行锐化和...
  • 去年年末我学习了天津科技大学杨淑莹老师的《数字图像处理》课程,虽然课程有点老,但是内容还是比较经典的。课程最后有好几个数字图像处理的案例,都是基于Visual C++的,我使用Python实现其中的“细胞个数统计”,...
  • matlab图像处理关于细胞计数

    万次阅读 多人点赞 2018-02-28 19:32:35
    第1章 问题重述本题共给出了如下所示的二十五张图片,每张图片都是显微镜下对运动精子静态观察的微观显示,每张图片中都含有很多条精子,随机选取一张精子的静态图片,以第十张图片为例,从图片1-2中可以看出,精子...
  • 基于图像处理的目标数量的自动计数方法可以对采集到的图像进行处理来实现自动计数,也可以先用采集到的图像减去背景图像从而得到一个差值图像,然后对差值图像进行处理实现计数。无论哪种方式,都需要首先进行目标和...
  • 图像分割与计数

    2020-07-29 14:18:17
    本资源压缩包打开后为一个.m文件和一张.jpg图片,实现数字图像处理中的二值化;直方图;腐蚀与膨胀;图形计数等功能
  • 【OpenCV实战】两种不同情况下的目标计数Python实现详解(含代码)一级目录二级目录三级目录 一级目录 二级目录 三级目录
  • 细胞图像分割与计数

    2020-07-30 23:32:24
    用matlab实现细胞计数功能,能够对粘连细胞进行计数。主要是论文类,方法。大致了解matlab
  • 1.根据颜色特征将菌落分为彩色和消色差图像(两种后序处理方法将不同),方法为计算R,G,B分量的均值,再计算它们的标准差,大于阈值的是彩色图像,小于的是消色差图像。 。。。未完待续 思路源自An automated ...
  • 该文档详细介绍了基于数字图像处理的骨髓细胞计数方法,通过比较多种方法来获得最佳解决途径,对我们认识数字图像处理以及MATLAB基本使用方法有很大帮助
  • 随着计算机技术和数字图像技术的快速发展,图像计数方法已经成为当今计数方法的一种重要手段,其目的就是从图像中准确获得某种物体的外观轮廓信息,进一步测量物体的特征参数并加以分析,以便于我们对物体进行轮廓...
  • 利用MATLAB对图像中物体进行计数

    千次阅读 2020-02-16 17:30:43
    ** 利用MATLAB对一张图片中相同得物体进行计数。 ** MATLAB中已有函数可对二值...因此我们需要做的是对图像进行处理,包括二值化,除噪等。 若直接将图像转化为二值图像进行计数,则无法得到正确数据。 如 clc; clo...
  • 形态学:对象计数

    千次阅读 2015-08-05 12:10:27
    形态学:对象计数 ...通常用于处理二值图像。 形态计数: 我们可以使用scipy.ndimage中的measurements模块来实现二值图像计数和度量功能。所谓的二值图像是指图像的每个像素只取两个值(一般是0和1)
  • 根据细胞的颜色,数出多少个细胞,图形图像处理技术,图像分割
  • 包装盒、纸张、PCB计数系统

    千次阅读 2013-04-29 23:32:18
    鉴于现代数字图像采集技术已经可以很方便地采集到清晰的目标图像,且速度较快,为此提出了非接触视觉图像分析的计数方法,试图以精度较高的图像摄取装置和高效的后台处理算法来解决这个问题。 一、系统简介 ...
  • Python语言用OpenCV实现Hough圆变换对图像圆形计数。包括图片,解压即可运行。
1 2 3 4 5 ... 20
收藏数 33,285
精华内容 13,314
关键字:

图像处理计数