2014-05-25 21:15:11 nannan_smile 阅读数 1297
  • 学习OpenCV3.2+QT5+ffmpeg实战开发视频编辑器视频教程

    OpenCV3.2+QT5+ffmpeg实战开发视频编辑器视频培训课程概况:教程中会讲解到基于opencv视频和摄像机录制、播放和播放进度控制,多视频图像合并、多视频图像融合、剪切、视频亮度、对比度、尺寸(近邻插值(手动实现),双线性插值,图像金字塔)、颜色格式(灰度图,二值化(阈值)),旋转镜像,视频裁剪(ROI),视频水印(ROI+weight),导出处理后的视频(包含音频,使用ffmpeg工具对音频进行抽取、剪切和终于opencv处理的视频合并)。

    20609 人正在学习 去看看 夏曹俊

我们通常得到的彩色图像都是24位真彩色图像,每个像素占用了3个字节,每个字节分别表示RGB三个颜色中的一种,在RGB模型中,如果R=G=B,则颜色显示一种灰度颜色,这时R、G、B的值就是灰度值;

灰度化处理是图像处理的第一步,经过灰度化处理的图像只包含亮度信息,不包含色彩信息,灰度图像便于存储,也能提高处理效率。根据彩色图像和灰度图像的对应关系,将24位真彩色位图转化为256级的灰度图像,灰度化处理去掉了图像的色彩信息,只留下亮度信息,主要有三种方法:最大值法、平均值法、加权平均法。


2019-11-29 10:28:09 AndroidAlvin 阅读数 90
  • 学习OpenCV3.2+QT5+ffmpeg实战开发视频编辑器视频教程

    OpenCV3.2+QT5+ffmpeg实战开发视频编辑器视频培训课程概况:教程中会讲解到基于opencv视频和摄像机录制、播放和播放进度控制,多视频图像合并、多视频图像融合、剪切、视频亮度、对比度、尺寸(近邻插值(手动实现),双线性插值,图像金字塔)、颜色格式(灰度图,二值化(阈值)),旋转镜像,视频裁剪(ROI),视频水印(ROI+weight),导出处理后的视频(包含音频,使用ffmpeg工具对音频进行抽取、剪切和终于opencv处理的视频合并)。

    20609 人正在学习 去看看 夏曹俊

阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:https://space.bilibili.com/474380680

本篇文章将通过灰度化和二值化&二值图像的腐蚀和膨胀的原理来介绍opencv图像处理

灰度化和二值化

1.1、图像二值化基本原理:

对灰度图像进行处理,设定阈值,在阈值中的像素值将变为1(白色部分),阈值为的将变为0(黑色部分)。

1.2、图像二值化处理步骤:

(1)先对彩色图像进行灰度化

//img为原图,imgGray为灰度图
cvtColor(img, imgGray, CV_BGR2GRAY);

(2)对灰度图进行二值化

//imgGray为灰度图,result为二值图像
//100~255为阈值,可以根据情况设定
//在阈值中的像素点将变为0(白色部分),阈值之外的像素将变为1(黑色部分)。
threshold(imgGray, result, 100, 255, CV_THRESH_BINARY);

1.3、demo

#include<iostream>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\core\core.hpp>
#include <opencv2\imgproc\imgproc.hpp>
 
using namespace std;
using namespace cv;
 
int main()
{
    Mat img, imgGray,result;
    img = imread("test.jpg");
    if (!img.data) {
        cout << "Please input image path" << endl;
        return 0;
    }
    imshow("原图", img);
    cvtColor(img, imgGray, CV_BGR2GRAY);
    imshow("灰度图", imgGray);
    //blur(imgGray, imgGray, Size(3, 3));
    threshold(imgGray, result, 100, 255, CV_THRESH_BINARY);
    imshow("二值化后的图", result);
    imwrite("二值化的二维码.jpg", result);
    cout << "图片已保存" << endl;
    waitKey();
 
    return 0;
}

1.4、效果:

19956127-0e08fb5e8316a0f4.png

二、腐蚀与膨胀

2.1 腐蚀的原理:

二值图像前景物体为1,背景为0.假设原图像中有一个前景物体,那么我们用一个结构元素去腐蚀原图的过程是这样的:遍历原图像的每一个像素,然后用结构元素的中心点对准当前正在遍历的这个像素,然后取当前结构元素所覆盖下的原图对应区域内的所有像素的最小值,用这个最小值替换当前像素值。由于二值图像最小值就是0,所以就是用0替换,即变成了黑色背景。从而也可以看出,如果当前结构元素覆盖下,全部都是背景,那么就不会对原图做出改动,因为都是0.如果全部都是前景像素,也不会对原图做出改动,因为都是1.只有结构元素位于前景物体边缘的时候,它覆盖的区域内才会出现0和1两种不同的像素值,这个时候把当前像素替换成0就有变化了。因此腐蚀看起来的效果就是让前景物体缩小了一圈一样。对于前景物体中一些细小的连接处,如果结构元素大小相等,这些连接处就会被断开。

2.2 膨胀的原理:

二值图像前景物体为1,背景为0.假设原图像中有一个前景物体,那么我们用一个结构元素去膨胀原图的过程是这样的:遍历原图像的每一个像素,然后用结构元素的中心点对准当前正在遍历的这个像素,然后取当前结构元素所覆盖下的原图对应区域内的所有像素的最大值,用这个最大值替换当前像素值。由于二值图像最大值就是1,所以就是用1替换,即变成了白色前景物体。从而也可以看出,如果当前结构元素覆盖下,全部都是背景,那么就不会对原图做出改动,因为都是0.如果全部都是前景像素,也不会对原图做出改动,因为都是1.只有结构元素位于前景物体边缘的时候,它覆盖的区域内才会出现0和1两种不同的像素值,这个时候把当前像素替换成1就有变化了。因此膨胀看起来的效果就是让前景物体胀大了一圈一样。对于前景物体中一些细小的断裂处,如果结构元素大小相等,这些断裂的地方就会被连接起来。
参考
https://blog.csdn.net/chenyuping333/article/details/81483593
https://blog.csdn.net/woainishifu/article/details/60778033
阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:https://space.bilibili.com/474380680

2013-11-24 17:09:55 Geng19930909 阅读数 9321
  • 学习OpenCV3.2+QT5+ffmpeg实战开发视频编辑器视频教程

    OpenCV3.2+QT5+ffmpeg实战开发视频编辑器视频培训课程概况:教程中会讲解到基于opencv视频和摄像机录制、播放和播放进度控制,多视频图像合并、多视频图像融合、剪切、视频亮度、对比度、尺寸(近邻插值(手动实现),双线性插值,图像金字塔)、颜色格式(灰度图,二值化(阈值)),旋转镜像,视频裁剪(ROI),视频水印(ROI+weight),导出处理后的视频(包含音频,使用ffmpeg工具对音频进行抽取、剪切和终于opencv处理的视频合并)。

    20609 人正在学习 去看看 夏曹俊

    囧,ADK还要更新一大截。所以我还是接着写吧,接下来是数字图像的相关文章,全部使用Python实现。

    首先讲的是灰度化。

    开始,我们先讲讲什么是灰度。

    大家都知道,一幅图片有很多个像素点,对于RGB图像来说,像素点是有RGB值的。当R=G=B时,我们就称这种颜色是一种灰度,由于RGB都只占8位,所以这里我们说的灰度也只有256种(0 - 255)。那么对于一张RGB彩色图,我们怎么让它变成一张合理的灰度图呢?

    有以下四种方法:

          1.分量法:

             对于每一个像素点,取其任意一种(R或G或B)为该点的灰度值,显然这种方法不是很合理,所以我就不多做叙述。

          2.最大值法:

            对于每一个像素点,取Max(R,G,B)为该点的灰度值。我也不多做叙述。

          3.平均值发:

            对于每一个像素点,取Avg(R,G,B)为该点的灰度值。我也不多做叙述。

          4.加权平均法:

           对于每一个像素点,由于人眼对红色光,绿色光,蓝色光的敏感程度不同而赋予不同的权重,从而得到该点的灰度值。

                       公式如下:

                              Gray = 0.30 * R + 0.59 * G + 0.11 *B

          

#灰度化
def greyyed():
    global greyyedImage
    image = originalImage.convert('RGB')
    h,w = image.size
    greyyedImage = Image.new('L',(h,w))
    opix = image.load()
    npix = greyyedImage.load()
    for i in range (h):
        for j in range (w):
            npix[i,j] = opix[i,j][0] * 0.299 + opix[i,j][1] * 0.587 + opix[i,j][2] * 0.114
    showPicture(greyyedImage , newCanvas)
    histogram(greyyedImage , newHisCanvas)

         这是对于RGB图的灰度化方法,其中我使用了Python Image Library(PIL)库来对图像进行操作,图像的'L'模式就是表示这个图示一个8位的灰度图。

         然后对于图像来说,并不是只有24位图(RGB),还有一些是调色板图像,我们需要做的是用同样的方法,不用改变原图的索引,而直接对调色板灰度化就行了。这些可能对C++,Java来说需要一些实现,但是对于Python来说,只需要建立一个灰度图'L'然后再把原图复制过去就行了。

        

#调色板图像灰度化
def colorGrey():
    image = originalImage.convert('P')
    showPicture(image , oldCanvas)
    h,w = image.size
    processImage = Image.new('L' , (h , w))
    opix = image.load()
    npix = processImage.load()
    for i in range(h):
        for j in range(w):
            npix[i,j] = opix[i,j]
    showPicture(processImage , newCanvas)
    histogram(processImage , newHisCanvas)
        由于我的UI在里边,所以这个代码你们可能不用直接使用。你们可以添加自己的显示方法来查看这个图像,比如image.save(),image.show()等。

        然后如果你不是学习如何灰度化,你可以使用PIL的库函数image.convert(),转成灰度图只需要对image这个对象使用这个函数。

#灰度化库函数
def Grey(img):
    newImage = img.convert('L')

    以下是效果图:

     

    Owari


2019-06-21 17:35:53 lzwarhang 阅读数 5868
  • 学习OpenCV3.2+QT5+ffmpeg实战开发视频编辑器视频教程

    OpenCV3.2+QT5+ffmpeg实战开发视频编辑器视频培训课程概况:教程中会讲解到基于opencv视频和摄像机录制、播放和播放进度控制,多视频图像合并、多视频图像融合、剪切、视频亮度、对比度、尺寸(近邻插值(手动实现),双线性插值,图像金字塔)、颜色格式(灰度图,二值化(阈值)),旋转镜像,视频裁剪(ROI),视频水印(ROI+weight),导出处理后的视频(包含音频,使用ffmpeg工具对音频进行抽取、剪切和终于opencv处理的视频合并)。

    20609 人正在学习 去看看 夏曹俊


原图如下
原图

1.灰度化

在这里插入图片描述

参考《Python图像灰度变换及图像数组操作》实现以下几种灰度化

获取图片及显示图片的通用方法如下:

from PIL import Image
import matplotlib.pyplot as plt
import numpy as np

#获取图片
def getimg():
  return Image.open("f:/pic/timg.jpg")
  
#显示图片
def showimg(img, isgray=False):
  plt.axis("off")
  if isgray == True:
    plt.imshow(img, cmap='gray')
  else: 
    plt.imshow(img)
  plt.show()

PIL库自带方法实现灰度化

im = getimg()
im_gray = im.convert('L')
showimg(im_gray, True)

1.1浮点算法

im = getimg()
im = np.array(im)
im[:,:,0] = im[:,:,0]*0.3
im[:,:,1] = im[:,:,1]*0.59
im[:,:,2] = im[:,:,2]*0.11
im = np.sum(im, axis=2)
showimg(Image.fromarray(im), True)

1.2.整数算法

im1 = getimg()
#创建数组时指定数据类型,否则默认uint8乘法运算会溢出
im1 = np.array(im1, dtype=np.float32)
im1[...,0] = im1[...,0]*30.0
im1[...,1] = im1[...,1]*59.0
im1[...,2] = im1[...,2]*11.0
im1 = np.sum(im1, axis=2)
im1[...,:] = im1[...,:]/100.0
showimg(Image.fromarray(im1), True)

1.3.平均值法

im2 =  getimg()
im2 = np.array(im2, dtype=np.float32)
im2 = np.sum(im2, axis=2)
im2[...,:] = im2[...,:]/3.0
showimg(Image.fromarray(im2), True)

1.4.移位法

im3 = getimg()
im3 = np.array(im3, dtype=np.int32)
im3[...,0] = im3[...,0]*28.0
im3[...,1] = im3[...,1]*151.0
im3[...,2] = im3[...,2]*77.0
im3 = np.sum(im3, axis=2)

arr = [np.right_shift(y.item(), 8) for x in im3 for y in x] 
arr = np.array(arr)
arr.resize(im3.shape)
showimg(Image.fromarray(arr), True)

1.5.单通道法(只取绿色通道)

im4 = getimg()
im4 = np.array(im4, dtype=np.int32)
im4[...,0] = 0
im4[...,2] = 0
im4 = np.sum(im4, axis=2)
showimg(Image.fromarray(im4), True)

2.二值化

2.1.取中间阀值127

在这里插入图片描述

im5 = getimg()
im5 = np.array(im5.convert('L'))
im5 = np.where(im5[...,:] < 127, 0, 255)
showimg(Image.fromarray(im5), True)

2.2.取所有像素点灰度的平均值

在这里插入图片描述

im = getimg()
im_gray1 = im.convert('L')
im_gray1 = np.array(im_gray1)
avg_gray = np.average(im_gray1)
im_gray1 = np.where(im_gray1[...,:] < avg_gray, 0, 255)
showimg(Image.fromarray(im_gray1), True)

3.灰度变换

3.1.反相

在这里插入图片描述

im = getimg()
im_gray = im.convert('L')
im_arr = np.array(im_gray)
im1 = 255 - im_arr 
showimg(Image.fromarray(im1))

3.2.将像素值变换到100~200之间

在这里插入图片描述

im = getimg()
im_gray = im.convert('L')
im2 = (100.0/255)*im_gray +100
showimg(Image.fromarray(im2))

3.3.将像素值求平方,使较暗的像素值变得更小

在这里插入图片描述

im = getimg()
im_gray = im.convert('L')
im3 = 255.0*(im_gray /255.0)**2
showimg(Image.fromarray(im3))

3.4.灰度变换函数对比

在这里插入图片描述

plt.rcParams['font.sans-serif'] = ['SimHei'] 
plt.title('灰度变换函数图像')
plt.xlabel('像素值')
plt.ylabel('变换后像素值')

x1 = np.arange(0, 256)
y1 = np.arange(0, 256)

f1, = plt.plot(x1, y1, '--')

y2 = 255 - x1
f2, = plt.plot(x1, y2, 'y')

y3 = (100.0/255)*x1 + 100
f3, = plt.plot(x1, y3, 'r:')

y4 = 255.0*(x1/255.0)**2
f4, = plt.plot(x1, y4, 'm--')
plt.legend((f1, f2, f3, f4), ('y=x','y=255-x','y=(100.0/255)*x+100','y=255.0*(x/255.0)**2'),loc='upper center')
plt.show()
2012-11-07 16:18:25 ggtaas 阅读数 5059
  • 学习OpenCV3.2+QT5+ffmpeg实战开发视频编辑器视频教程

    OpenCV3.2+QT5+ffmpeg实战开发视频编辑器视频培训课程概况:教程中会讲解到基于opencv视频和摄像机录制、播放和播放进度控制,多视频图像合并、多视频图像融合、剪切、视频亮度、对比度、尺寸(近邻插值(手动实现),双线性插值,图像金字塔)、颜色格式(灰度图,二值化(阈值)),旋转镜像,视频裁剪(ROI),视频水印(ROI+weight),导出处理后的视频(包含音频,使用ffmpeg工具对音频进行抽取、剪切和终于opencv处理的视频合并)。

    20609 人正在学习 去看看 夏曹俊
package com.scy.grayvalue2;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.Menu;
import android.widget.ImageView;

/**
 * 思路如下:
 
     1.读取or照相,得到一张ARGB图片。
 
     2.转化为bitmap类,并对其数据做如下操作:
 
        A通道保持不变,然后逐像素计算:X = 0.3×R+0.59×G+0.11×B,并使这个像素的值新R,G,B值为X,即:
 
        new_R = X, new_G = X, new_B = X
 
        例如:原来一个像素是4个byte,分别为ARGB,现在这个像素应该为AXXX。
 
      3.将上一步骤得到的bitmap图像写到输出流里面,并保存为图片。或者直接显示在ImageView上。

 * @author scy
 *
 */
public class MainActivity extends Activity 
{
	private byte[] rawData;
	private ImageView imageView;
	
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView = (ImageView)findViewById(R.id.image);
        //将bitmap转换成一个伪灰度图,再转化成一个byte[]
        //将byte[]转换为bitmap
//		Bitmap bitmapOrg = BitmapFactory.decodeByteArray(rawData, 0, rawData.length);
        Bitmap bitmapOrg = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
		Bitmap bitmapNew = bitmapOrg.copy(Config.ARGB_8888, true); 
		//Bitmap bitmapNew = bitmapOrg.copy(Config.ARGB_8888, true);
		if(bitmapNew == null)
			Log.i("TAG", "null");
		Log.i("TAG", "copy end");
		/**
		 * 一种简单的灰度化算法,但是这种方法需要修改每个点的像素,如果一张图片比较大,则这个处理速度就堪忧了
		 * 往往需要创建一个线程来处理
		 */
        for(int i = 0;i<bitmapNew.getWidth();i++)
        {
      	  for(int j =0;j<bitmapNew.getHeight();j++)
      	  {	
                int col = bitmapNew.getPixel(i, j);//获取点(i,j)处的像素
                //分别获取ARGB的值
                int alpha = col&0xFF000000;
                int red = (col&0x00FF0000)>>16;
                int green = (col&0x0000FF00)>>8;
                int blue = (col&0x000000FF);
                //用公式X = 0.3×R+0.59×G+0.11×B计算出X代替原来的RGB
                int gray = (int)((float)red*0.3+(float)green*0.59+(float)blue*0.11);
                //新的ARGB
                int newColor = alpha|(gray<<16)|(gray<<8)|gray;
                //在点(i,j)处设置新的像素
                bitmapNew.setPixel(i, j, newColor);
                //Log.v("tag",  Integer.toHexString(col));  
      	  }
        }
        Log.i("TAG", "pro end");
        sendMsg(bitmapNew);
        /*
        File file = new File(Environment.getExternalStorageDirectory()+File.separator+"gray"+number+".jpg");
        OutputStream out;
		try {
			out = new FileOutputStream(file);
			if(bitmapNew.compress(Bitmap.CompressFormat.JPEG, 100, out))
				Log.i("TAG", "success");
			out.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		*/
	}

	private void sendMsg(Bitmap bitmapNew)
	{
		imageView.setImageBitmap(bitmapNew);
	}
}

/**
 * drawableToBitmap
 */
/*
 public static Bitmap drawableToBitmap(Drawable drawable) {
        
        Bitmap bitmap = Bitmap
                        .createBitmap(
                                        drawable.getIntrinsicWidth(),
                                        drawable.getIntrinsicHeight(),
                                        drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
                                                        : Bitmap.Config.RGB_565);
        Canvas canvas = new Canvas(bitmap);
        //canvas.setBitmap(bitmap);
        drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
        drawable.draw(canvas);
        return bitmap;
}
 */

/**
 * Bitmap2Bytes
 */
/*
 private byte[] Bitmap2Bytes(Bitmap bm)
 {
	ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
	bm.compress(Bitmap.CompressFormat.PNG, 100, baos); 
 	return baos.toByteArray();
 }
*/

/**
 * Bytes2Bimap
 */
/*
 private Bitmap Bytes2Bimap(byte[] b)
 {
    if(b.length ==0)
    {
    	return null;
    }

	return BitmapFactory.decodeByteArray(b, 0, b.length);

  }
*/


最后介绍了几种图片转换方法。

下面是另外一种灰度化方法:

package com.scy.grayvalue;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.os.Bundle;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.view.Menu;
import android.widget.ImageButton;
import android.widget.ImageView;

public class MainActivity extends Activity  
{
	private Bitmap bitmap,buffer;
	private ImageView imageView;
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);      
           
        bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
        buffer = convert2Gray(bitmap);
       /*
        //创建八位图
        buffer = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
        //将八位图作为画布
        Canvas canvas = new Canvas(buffer);
        Paint paint = new Paint();

        paint.setColorFilter(filter);
        
        canvas.drawBitmap(buffer, 0, 0, paint);
        canvas.save();
         */
        imageView = (ImageView)findViewById(R.id.image);
        imageView.setImageBitmap(buffer);
 
        /*
        File file = new File("/mnt/1.jpg");
        FileOutputStream os = null;
        try
		{
			os = new FileOutputStream(file);
			bitmap.compress(Bitmap.CompressFormat.JPEG, 80, os);
			os.flush();
			os.close();
		} catch (FileNotFoundException e)
		{
			e.printStackTrace();
		} catch (IOException e)
		{
			e.printStackTrace();
		}
		*/
        
        
    }
	private Bitmap convert2Gray(Bitmap bitmap)
	{
        /**
         *  [ a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t ] When applied to a color [r, g, b, a], 
         *  the resulting color is computed as (after clamping) 
         *  R' = a*R + b*G + c*B + d*A + e; G' = f*R + g*G + h*B + i*A + j; 
         *  B' = k*R + l*G + m*B + n*A + o; A' = p*R + q*G + r*B + s*A + t; 
         */
        ColorMatrix colorMatrix = new ColorMatrix();
        /**
         * Set the matrix to affect the saturation(饱和度) of colors. 
         * A value of 0 maps the color to gray-scale(灰阶). 1 is identity
         */
        colorMatrix.setSaturation(0);
        ColorMatrixColorFilter filter = new ColorMatrixColorFilter(colorMatrix);
        
        Paint paint = new Paint();
        paint.setColorFilter(filter);
        
        Bitmap result = bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
        Canvas canvas = new Canvas(result);
        canvas.drawBitmap(bitmap, 0, 0, paint);
        return result;
	}

}


 

没有更多推荐了,返回首页