# QHBinimageMan
**Repository Path**: chenqihui/qhbinimage-man
## Basic Information
- **Project Name**: QHBinimageMan
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 1
- **Created**: 2021-03-17
- **Last Updated**: 2021-04-15
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 图像の二值图
--
本篇介绍的是图像的二值图,讲解由 **彩色图 -> 灰度图 -> 二值图 的转换过程和基于 Swift 实现的 Mac 工具** [QHBinimageMan](https://gitee.com/chenqihui/qhbinimage-man) 。让读者进一步了解图像的像素和像素间处理的图像技术。类似之前的《[iOS 隐形水印之 LSB 实现](https://mp.weixin.qq.com/s/6jHA2xKIeS13k30ztHYfEA)》,也是对图像的 RGB 像素进行读取 & 修改。
# 工具
[QHBinimageMan](https://gitee.com/chenqihui/qhbinimage-man) 二值图生成工具。可进行阈值、分辨率缩放的控制生成二值图(项目工程相对简单,仅供参考)。
# 彩色图
在 MacOS/iOS 下,可分别通过 NSImage/UIImage 转换 CVPixelBuffer 来读取 RGB 像素值,此步骤是由 CoreVideo 框架 来解码图片。
~~~
// 创建 CVPixelBuffer
var temp_pb: CVPixelBuffer?
let r = CVPixelBufferCreate(kCFAllocatorDefault, w, h, kCVPixelFormatType_32ARGB, opt, &temp_pb);
// 读取原数据
let pb_data = CVPixelBufferGetBaseAddress(pb)
~~~
# 灰度图
灰度是指 红色、绿色和蓝色分量在 RGB空间的值是一样。使用彩色图均先转换为灰度图,方便分离前后景,从而生成二值图。
彩色转灰度:
采用 BT.709 色域来转换,这其实就是 yuv 的 亮度值 y
~~~
// rgb 转换 y 值
let red = Float(data[offset+1]) * 0.2126
let green = Float(data[offset+2]) * 0.7152
let blue = Float(data[offset+3]) * 0.0722
let v = UInt8(red + green + blue)
// rgb 设置成 y 值
data[offset+1] = v
data[offset+2] = v
data[offset+3] = v
~~~
# 直方图
直方图可以更好地可视化来选择二值图的阈值。这里也可以说明为什么需要使用灰度图,而不是彩色图直接转换二值图,因为彩色图的直方图有 RGB 三个,没有灰度图的方便确认阈值。
**阈值化:**
> In many vision applications, it is useful to be able to separate out the regions of the image corresponding to objects in which we are interested, from the regions of the image that correspond to background. Thresholding often provides an easy and convenient way to perform this segmentation on the basis of the different intensities or colors in the foreground and background regions of an image.
>
> In addition, it is often useful to be able to see what areas of an image consist of pixels whose values lie within a specified range, or band of intensities (or colors). Thresholding can be used for this as well.
工具生成的是灰度图的直方图,分成 16 个单位的灰度颜色强度的平均值来展示:
~~~
// 分块
var i = 0
for p in ps {
pss[i/16] += p
i += 1
}
i = 0
for p in pss {
// 计算平均值
pss[i] = p/16
// 最高颜色强度值
maxP = max(maxP, pss[i])
i += 1
}
~~~
可以看出此示例灰度图的颜色强度主要分布在头部、尾部和中间,即分别对应黑(0)、白(256)和灰色(128)。
# 二值图
二值图通常就是指黑白图,像素只有两个值,分别是 (1 或 255) 和 0。
本工具将在阈值区间内的颜色强度记为 1,不符合的记为 0。明显看出示例图片的黑色点,即直方图的 0 - 16 区域是图片的前景边线,所以可以选择 (0, 20) 的区域作为阈值区域。
~~~
let v = data[offset+1]
// 阈值区间筛选 & 记录
if v > minbin && v < maxbin {
matrixLine += "1"
}
else {
matrixLine += "0"
}
~~~
阈值决定了要显示的部分,如下是选择不同阈值的效果图。可以明显看出它们包含 ”1“ 的个数是不同的,即细节的差异。**建议将工具生成的二值图,复制到 Sublime Text 等工具看是 0-1 对齐效果更佳**。
(0, 20) |
(0, 120) |
# 降分辨率
可先看看 [一张图片裁剪后竟然可重组为四张!_分辨率 - 搜狐新闻](https://www.sohu.com/a/288969657_472787) 生动的演示了降分辨率。
而图片经过多次剪切,仍然可以看出原画面。工具参考此来降分辨率,通过隔行和隔列进行裁剪来缩放。
~~~
// 缩放比例
let ss = max(ratio, 1)
// 满足的行列进行裁剪记录
for y in 0..
 |
 |