如何将 JPG 图像的整数数组转换为 JPG 图像?
How can I convert a array of integers of a JPG image to a JPG image?
我在机器人上安装了摄像头。长话短说,相机输出二进制数组,我认为这是一个 JPG 编码流。我这样说是因为我使用的库中的很多方法都提示它是 JPG 编码的,第一个和最后两个字节分别是 255 216
和 255 217
,这是神奇的JPG 文件格式的编号。
如何将这个整数数组转换为 Python 格式的 JPG 文件?
我尝试将整数数组写入 .JPG 文件,但该文件被标记为已损坏。
长话短说,我有一个 ArduCam 连接到一个 esp8266(字面意思是一个可以连接到 WiFi 的 Arduino 板)。我有一个捕获照片的脚本,并将原始图像数据上传到 esp8266 上托管的服务器。
这是我使用的主要方法:
void camCapture(ArduCAM myCAM) {
WiFiClient client = server.client(); // ignore this stuff
uint32_t len = myCAM.read_fifo_length();
if (len >= MAX_FIFO_SIZE) //8M
{
Serial.println(F("Over size."));
}
if (len == 0 ) //0 kb
{
Serial.println(F("Size is 0."));
}
myCAM.CS_LOW();
myCAM.set_fifo_burst();
if (!client.connected()) return;
String response = "[";
i = 0;
while ( len-- ) // this is where the raw image is collection
{
temp_last = temp;
temp = SPI.transfer(0x00);
//Read JPEG data from FIFO
if ( (temp == 0xD9) && (temp_last == 0xFF) ) //If find the end ,break while,
{
buffer[i++] = temp; //save the last 0XD9
response += String(int(temp)) + "], ";
response += String(i);
if (!client.connected()) break;
Serial.print(String(i));
server.send(200,"text/plain",response); // this is where the image is uploaded
is_header = false;
i = 0;
myCAM.CS_HIGH();
break;
}
if (is_header == true)
{
//Write image data to buffer if not full
if (i < bufferSize)
buffer[i++] = temp;
else
{
//Write bufferSize bytes image data to file
if (!client.connected()) break;
i = 0;
buffer[i++] = temp;
}
response += String(int(temp)) + ",";
}
else if ((temp == 0xD8) & (temp_last == 0xFF))
{
is_header = true;
buffer[i++] = temp_last;
buffer[i++] = temp;
response += String(int(temp_last)) + "," + String(int(temp)) + ",";
}
}
}
原始图像数据如下所示:
255,216,255,224,0,16,74,70,73,70,0,1,1,1,0,0,0,0,0,0,255,219,74,74,74,74,74,74,74,74,74,74,74,74,74,74 [...] 64,143,255,217
现在我知道 jpeg 文件分别以 255,216 和 255,217 开头和结尾。所以我认为这是一个好兆头。此外,当我使用 jpeg html 代码时,它实际上将原始图像数据转换为实际图像。
这是我的 python 脚本,我在其中尝试将原始图像数据解码为 .jpg 文件:
import cv2
with open('img.txt') as file: # this is where I keep the raw image data
img = file.read()
img = img.split(',')
img = [int(i) for i in img]
tmpfile = open("tmp.jpg", "wb")
for i in img:
tmpfile.write(bytes(i))
tmpfile.close()
img = cv2.imread('tmp.jpg')
print(img)
cv2.imshow('img',img)
cv2.waitKey(0)
由于 bytes()
会将您的 int
转换为字节字符串。您可能已经从文件大小中注意到,因为它与 tmp.txt
.
中的值数量不匹配
将字节写入文件的正确方法如下:
import struct
...
for i in img:
tmpfile.write(struct.pack("B", i))
...
由于您在本例中使用的是 8 位值,因此您也可以使用 chr(i)
.
我在机器人上安装了摄像头。长话短说,相机输出二进制数组,我认为这是一个 JPG 编码流。我这样说是因为我使用的库中的很多方法都提示它是 JPG 编码的,第一个和最后两个字节分别是 255 216
和 255 217
,这是神奇的JPG 文件格式的编号。
如何将这个整数数组转换为 Python 格式的 JPG 文件?
我尝试将整数数组写入 .JPG 文件,但该文件被标记为已损坏。
长话短说,我有一个 ArduCam 连接到一个 esp8266(字面意思是一个可以连接到 WiFi 的 Arduino 板)。我有一个捕获照片的脚本,并将原始图像数据上传到 esp8266 上托管的服务器。 这是我使用的主要方法:
void camCapture(ArduCAM myCAM) {
WiFiClient client = server.client(); // ignore this stuff
uint32_t len = myCAM.read_fifo_length();
if (len >= MAX_FIFO_SIZE) //8M
{
Serial.println(F("Over size."));
}
if (len == 0 ) //0 kb
{
Serial.println(F("Size is 0."));
}
myCAM.CS_LOW();
myCAM.set_fifo_burst();
if (!client.connected()) return;
String response = "[";
i = 0;
while ( len-- ) // this is where the raw image is collection
{
temp_last = temp;
temp = SPI.transfer(0x00);
//Read JPEG data from FIFO
if ( (temp == 0xD9) && (temp_last == 0xFF) ) //If find the end ,break while,
{
buffer[i++] = temp; //save the last 0XD9
response += String(int(temp)) + "], ";
response += String(i);
if (!client.connected()) break;
Serial.print(String(i));
server.send(200,"text/plain",response); // this is where the image is uploaded
is_header = false;
i = 0;
myCAM.CS_HIGH();
break;
}
if (is_header == true)
{
//Write image data to buffer if not full
if (i < bufferSize)
buffer[i++] = temp;
else
{
//Write bufferSize bytes image data to file
if (!client.connected()) break;
i = 0;
buffer[i++] = temp;
}
response += String(int(temp)) + ",";
}
else if ((temp == 0xD8) & (temp_last == 0xFF))
{
is_header = true;
buffer[i++] = temp_last;
buffer[i++] = temp;
response += String(int(temp_last)) + "," + String(int(temp)) + ",";
}
}
}
原始图像数据如下所示:
255,216,255,224,0,16,74,70,73,70,0,1,1,1,0,0,0,0,0,0,255,219,74,74,74,74,74,74,74,74,74,74,74,74,74,74 [...] 64,143,255,217
现在我知道 jpeg 文件分别以 255,216 和 255,217 开头和结尾。所以我认为这是一个好兆头。此外,当我使用 jpeg html 代码时,它实际上将原始图像数据转换为实际图像。
这是我的 python 脚本,我在其中尝试将原始图像数据解码为 .jpg 文件:
import cv2
with open('img.txt') as file: # this is where I keep the raw image data
img = file.read()
img = img.split(',')
img = [int(i) for i in img]
tmpfile = open("tmp.jpg", "wb")
for i in img:
tmpfile.write(bytes(i))
tmpfile.close()
img = cv2.imread('tmp.jpg')
print(img)
cv2.imshow('img',img)
cv2.waitKey(0)
由于 bytes()
会将您的 int
转换为字节字符串。您可能已经从文件大小中注意到,因为它与 tmp.txt
.
将字节写入文件的正确方法如下:
import struct
...
for i in img:
tmpfile.write(struct.pack("B", i))
...
由于您在本例中使用的是 8 位值,因此您也可以使用 chr(i)
.