Octave图片转游戏代码脚本报错:rgb2gray不支持logical类型RGB
问题
运行Octave图片转游戏代码脚本时,处理1507.png时报错:
error: rgb2gray: RGB of invalid data type 'logical'
error: called from
colorspace_conversion_input_check at line 41 column 7
rgb2gray at line 61 column 5
FreeRiderImageMaker at line 31 column 15
重复运行、调整originY参数均无法解决,原脚本如下:
% The images must be in the same folder as this script. % The originY variable will be updated for each PNG file. originY = 3010000; % Threshold values modify which shades of grey are consirered scenery (0-255). threshold1 = 50; %black is 0 threshold2 = 0; %white is 255 % The origin modifies where the rider begins relative to the image. originX = 200; % Images can be made larger using the scale option. Use only whole numbers. % Note that there is a size limit for tracks uploaded to FRHD. scaleX = 2; scaleY = 2; % Loop through each PNG file until 2154.png. for n = 1505:2154 % Create the file name for the current PNG file. filename = sprintf('%04d.png', n); % Read the PNG file. image = imread(filename); % Create the file name for the output text file. outputFilename = sprintf('%04d.txt', n); % Open the output text file for writing. output = fopen(outputFilename, 'w'); grayImage = transpose(rgb2gray(image)); sceneryString = sprintf('#'); for j = 1:(size(grayImage,2)*scaleY) currentColor = 2; % 2 for white, 1 for gray, 0 for black for i = 1:size(grayImage,1) if originY+j >= 0 row = lower(dec2base(originY+j, 32)); else row = strcat('-', lower(dec2base(-(originY+j), 32))); end; if originX+i*scaleX >= 0 xPos = lower(dec2base(originX+i*scaleX, 32)); else xPos = strcat('-', lower(dec2base(-(originX+i*scaleX), 32))); end; pixel = grayImage(i,ceil(j/scaleY)); if currentColor == 2 if pixel > threshold2 continue; elseif pixel < threshold1 fprintf(output, '%s %s ', xPos, row); currentColor = 0; else sceneryString = sprintf('%s%s %s ', sceneryString, xPos, row); currentColor = 1; end; elseif currentColor == 0 if pixel < threshold1 continue; elseif pixel > threshold2 fprintf(output, '%s %s,', xPos, row); currentColor = 2; else fprintf(output, '%s %s,', xPos, row); sceneryString = sprintf('%s%s %s ', sceneryString, xPos, row); currentColor = 1; end; else if pixel > threshold2 sceneryString = sprintf('%s%s %s,', sceneryString, xPos, row); currentColor = 2; elseif pixel < threshold1 sceneryString = sprintf('%s%s %s,', sceneryString, xPos, row); fprintf(output, '%s %s ', xPos, row); currentColor = 0; else continue; end; end; end; if currentColor == 1 sceneryString = sprintf('%s%s %s,', sceneryString, xPos, row); elseif currentColor == 0 fprintf(output, '%s %s,', xPos, row); end; end; sceneryString = sprintf('%s#', sceneryString); fprintf(output, '%s', sceneryString); fclose(output); % Increase the value of originY by 2000 for the next iteration of the loop. originY = originY + 2000; end;
解决方案
核心原因
1507.png是单通道灰度图/二值图,imread读取后返回logical类型数组(而非RGB三通道数组),但rgb2gray仅支持输入RGB格式图像,因此触发类型不匹配报错。
修复方案
在调用rgb2gray前增加图像格式判断,对单通道图像直接做格式转换,无需调用rgb2gray。修改后的完整脚本如下:
% The images must be in the same folder as this script. % The originY variable will be updated for each PNG file. originY = 3010000; % Threshold values modify which shades of grey are consirered scenery (0-255). threshold1 = 50; %black is 0 threshold2 = 0; %white is 255 % The origin modifies where the rider begins relative to the image. originX = 200; % Images can be made larger using the scale option. Use only whole numbers. % Note that there is a size limit for tracks uploaded to FRHD. scaleX = 2; scaleY = 2; % Loop through each PNG file until 2154.png. for n = 1505:2154 % Create the file name for the current PNG file. filename = sprintf('%04d.png', n); % Read the PNG file. image = imread(filename); % --- 新增:兼容单通道/逻辑型图像 --- if ndims(image) <= 2 % 单通道图像直接转为uint8格式(二值图自动映射为0/255) grayImage = transpose(uint8(image)); else % RGB三通道图像正常转灰度图 grayImage = transpose(rgb2gray(image)); end % --- 新增结束 --- % Create the file name for the output text file. outputFilename = sprintf('%04d.txt', n); % Open the output text file for writing. output = fopen(outputFilename, 'w'); sceneryString = sprintf('#'); for j = 1:(size(grayImage,2)*scaleY) currentColor = 2; % 2 for white, 1 for gray, 0 for black for i = 1:size(grayImage,1) if originY+j >= 0 row = lower(dec2base(originY+j, 32)); else row = strcat('-', lower(dec2base(-(originY+j), 32))); end; if originX+i*scaleX >= 0 xPos = lower(dec2base(originX+i*scaleX, 32)); else xPos = strcat('-', lower(dec2base(-(originX+i*scaleX), 32))); end; pixel = grayImage(i,ceil(j/scaleY)); if currentColor == 2 if pixel > threshold2 continue; elseif pixel < threshold1 fprintf(output, '%s %s ', xPos, row); currentColor = 0; else sceneryString = sprintf('%s%s %s ', sceneryString, xPos, row); currentColor = 1; end; elseif currentColor == 0 if pixel < threshold1 continue; elseif pixel > threshold2 fprintf(output, '%s %s,', xPos, row); currentColor = 2; else fprintf(output, '%s %s,', xPos, row); sceneryString = sprintf('%s%s %s ', sceneryString, xPos, row); currentColor = 1; end; else if pixel > threshold2 sceneryString = sprintf('%s%s %s,', sceneryString, xPos, row); currentColor = 2; elseif pixel < threshold1 sceneryString = sprintf('%s%s %s,', sceneryString, xPos, row); fprintf(output, '%s %s ', xPos, row); currentColor = 0; else continue; end; end; end; if currentColor == 1 sceneryString = sprintf('%s%s %s,', sceneryString, xPos, row); elseif currentColor == 0 fprintf(output, '%s %s,', xPos, row); end; end; sceneryString = sprintf('%s#', sceneryString); fprintf(output, '%s', sceneryString); fclose(output); % Increase the value of originY by 2000 for the next iteration of the loop. originY = originY + 2000; end;
额外说明
- 如果
1507.png是二值图(仅0和1),转为uint8后会自动转为0和255,完全符合脚本中阈值判断逻辑(0为黑,255为白),无需调整阈值参数。 - 该修改同时兼容后续所有单通道格式的PNG图片,避免再次出现同类报错。
内容的提问来源于stack exchange,提问作者Labebeh
相关产品推荐
相关产品推荐

