我所做的是:
打开一个输入文件(txt),其RGB值为64色条目。
打开另一个输入文件,即带有颜色值(每个像素3个字节)的1024x1024位图。
从txt文件中读取并将其中的值分配到结构数组中。
结构数组保存R、G、B值和所述颜色的名称。接下来,我将读取RGB值的位图,并将它们与结构中的值进行比较。
我创建了一个for循环,以1,048,576作为限制,在内部创建了另一个for循环,其中64为限制,用于比较值。问题是比较的计数将导致67,108,864。理论最小值为1,048,576。
到目前为止,这就是我所拥有的:
for (int i = 0;!bitmap.eof(); i += 3)
{
unsigned char red, green, blue;
bitmap.read((char*)&blue, sizeof(unsigned char));
bitmap.read((char*)&green, sizeof(unsigned char));
bitmap.read((char*)&red, sizeof(unsigned char));
for (int j = 0; j < 64; j++)
{
if (int(blue) == bmiColors[j].b && int(green) == bmiColors[j].g && int(red) == bmiColors[j].r)
{
//cout << "B: " << int(b) << " G: " << int(g) << " R: " << int(r) << endl;
//cout << "Position: " << bitmap.tellg() << endl;
bmiColors[j].matchCount += 1;
count++;
}
else
{
bmiColors[j].skipCount += 1;
count++;
}
}
}
你会如何优化它呢?我得到的提示是使用像素颜色作为表中的索引。请帮帮我。
发布于 2022-06-04 22:35:25
将像素颜色用作表中的索引可能会有问题。颜色{255, 255, 255}
将具有索引16777215
(255*65536 + 255*256 + 255
)。它可能太大,也可能不太大。类似的想法可能是使用某种map
,比如unordered_map
,并将64 bmiColors
存储在其中,并将它们映射到bitmap
文件中的计数。
示例:
#include <cstdint>
#include <fstream>
#include <iostream>
#include <iterator>
#include <unordered_map>
// A class to store one pixel
struct RGB {
uint8_t r;
uint8_t g;
uint8_t b;
// compare two RGB:s:
bool operator==(const RGB& rhs) const { return r == rhs.r
&& g == rhs.g
&& b == rhs.b; }
// read one RGB from an istream:
friend std::istream& operator>>(std::istream& is, RGB& rgb) {
is.read(reinterpret_cast<char*>(&rgb.r), 1);
is.read(reinterpret_cast<char*>(&rgb.g), 1);
is.read(reinterpret_cast<char*>(&rgb.b), 1);
return is;
}
};
// A specialization of `std::hash` for RGB to be able to use it in an `unorderded_map`:
namespace std {
template<>
struct hash<RGB> {
size_t operator()(const RGB& rgb) const noexcept { return rgb.r << 16
| rgb.g << 8
| rgb.b; }
};
} // namespace std
然后主程序会
unordered_map
,bmiColors
。bitmap
文件中读取并使用bmiColors.find
查看颜色是否存在。如果存在value.,则增加映射的
int main() {
std::unordered_map<RGB, std::uint32_t> bmiColors;
{
std::ifstream bmi("bmi.bmp");
if(not bmi) return 1;
std::transform(std::istream_iterator<RGB>(bmi), std::istream_iterator<RGB>{},
std::inserter(bmiColors, bmiColors.end()), [](const RGB& rgb) {
return std::pair{rgb, 0};
});
}
if(std::ifstream bitmap("file.bmp"); bitmap) {
std::for_each(std::istream_iterator<RGB>(bitmap), std::istream_iterator<RGB>{},
[&bmiColors](const RGB& rgb) {
if(auto it = bmiColors.find(rgb); it != bmiColors.end()) {
++it->second;
}
});
}
// print the result
for(auto& [rgb, count] : bmiColors) {
if(count) {
std::cout << static_cast<unsigned>(rgb.r) << ' '
<< static_cast<unsigned>(rgb.g) << ' '
<< static_cast<unsigned>(rgb.b) << ' ' << count << '\n';
}
}
}
https://stackoverflow.com/questions/72504617
复制