现在,我有一张图片,要对他进行阈值分割,现在开始(完整代码在文章末尾):
首先简单了解一下什么是阈值分割,这个阈值就表示一个界限值,使用这个值来区分图像里面不同颜色强度的部分,本次代码中超过阈值的为255(白),小于的就为0(黑),若把阈值从1000降为700则代表部分较低颜色强度的部分也可以列为超过阈值,所以白色的部分就会变大,就可以把比较特殊的地方挑出来。总结来说就是大于阈值的部分归为一类,小于阈值的部分归为另一类。
阈值分割是可以把图像当中有我们需要的使用的物体和画面,或者我们觉得有用的物体把它分离出来,去掉有干扰的背景像。可以应用到那种检测病灶的地方,例如把肺部患癌发白的地方给找出来等等...
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <iostream>
#include <fstream>
先写出头文件,具体含义上篇文章已经解释。
main函数部分:
unsigned int width = 1024;
unsigned int height = 1024;
size_t pixelCount = width * height;
void* pData = malloc(pixelCount * sizeof(short));
FILE* pFile = fopen("D:/OneDrive/sliced.img", "rb+");
if (pFile == NULL) {
free(pData);
return 0;
}
size_t rBite = fread(pData, sizeof(short), pixelCount, pFile);
fclose(pFile);
打开文件,读取内容,关闭文件。
void* pMask = malloc(pixelCount * sizeof(unsigned char));
memset(pMask, 0, pixelCount);//初始化为0
short* pSrc = (short*)pData;//pSrc 指向 pData(原始数据)
unsigned char* pDes = (unsigned char*)pMask;//pDes 指向 pMask(结果数据)
使用malloc函数动态分配了一个大小为pixelCount * sizeof(unsigned char)
字节的内存块,并将其地址赋给pMask指针。这个内存块用于存储分割后的结果,每个像素对应一个unsigned char类型的值。
使用memset函数将刚刚分配的内存块pMask
初始化为0。
将输入的原始数据pData
的地址强制类型转换为short类型指针pSrc
。为了方便后续对原始数据的访问和处理。
分配的结果数据的内存块pMask的地址强制类型转换为unsigned char类型指针pDes
。为了方便后续将阈值分割后的结果写入到pMask中。
这里定义了阈值tValue
为700。即,如果原始数据的某个像素值大于700,则在结果数据中对应的位置置为255(白色);否则置为0(黑色)。
for (size_t i = 0; i < pixelCount; ++i) {
if (*pSrc > tValue) {
*pDes = 255;
}
else {
*pDes = 0;
}
pSrc++;
pDes++;
}
核心的循环部分:
检查pSrc
指向的原始数据的当前像素值是否大于阈值tValue
。
if 是,将pDes
指向的结果数据的当前位置设置为255(即白色)。
else if 不是,将pDes
指向的结果数据的当前位置设置为0(即黑色)。
然后,分别将pSrc
和pDes
指针向后移动,以便处理下一个像素位置。
这样,循环结束后,pMask
中存储的数据就是根据阈值tValue分割后的结果,其中大于阈值的像素被标记为白色(255),小于等于阈值的像素被标记为黑色(0)。
FILE* pnewFile = fopen("newsliced.img", "wb");
fwrite(pMask, sizeof(unsigned char), pixelCount, pnewFile);
if (pnewFile == NULL) {
free(pMask);
return 0;
}
fclose(pnewFile);
free(pData);
free(pMask);
cout << "wancheng" << endl;
创建一个新文件newsliced,用fwrite将pMask的数据写入新文件。然后关闭文件,释放数据流。
在源文件中查看新文件。用mricro查看结果:
左边是原图像,右上是阈值为700时的图像,右下是阈值为1000时的图像。1000-700阈值降低,白色变多,印证文章开头。
完整代码:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
int main() {
unsigned int width = 1024;
unsigned int height = 1024;
size_t pixelCount = width * height;
void* pData = malloc(pixelCount * sizeof(short));
FILE* pFile = fopen("D:/OneDrive/sliced.img", "rb+");
if (pFile == NULL) {
free(pData);
return 0;
}
size_t rBite = fread(pData, sizeof(short), pixelCount, pFile);
fclose(pFile);
//保存分割的结果
void* pMask = malloc(pixelCount * sizeof(unsigned char));//分配一个新的内存块 pMask,大小为 pixelCount * sizeof(unsigned char),用来存储分割后的结果。
memset(pMask, 0, pixelCount);//初始化为0
short* pSrc = (short*)pData;//pSrc 指向 pData(原始数据)
unsigned char* pDes = (unsigned char*)pMask;//pDes 指向 pMask(结果数据)
short tValue = 700; // 阈值为700
for (size_t i = 0; i < pixelCount; ++i) {
if (*pSrc > tValue) {
*pDes = 255;
}
else {
*pDes = 0;
}
pSrc++;
pDes++;
}
//循环遍历每个像素,如果原始数据大于阈值 tValue,则将对应位置的 pDes 置为 255。
FILE* pnewFile = fopen("newsliced.img", "wb");
fwrite(pMask, sizeof(unsigned char), pixelCount, pnewFile);
if (pnewFile == NULL) {
free(pMask);
return 0;
}
fclose(pnewFile);
free(pData);
free(pMask);
cout << "wancheng" << endl;
}