Skip to content

Commit

Permalink
Add support of JPG files reading
Browse files Browse the repository at this point in the history
  • Loading branch information
ben committed May 14, 2023
1 parent 6dfa05e commit 661baa0
Show file tree
Hide file tree
Showing 13 changed files with 167 additions and 66 deletions.
6 changes: 4 additions & 2 deletions AmApi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@
#include "analyze/algorithm/ImagePair.h"
#include <sstream>

#include <jpeglib.h>
namespace am
{
using namespace common::types;
using namespace analyze;


AmApi::AmApi(const char *conf_path):
AmApi::AmApi(const char *conf_path, bool is_bmp):
loggerPtr(std::make_shared<am::common::Logger>("log.log")),
extractor(loggerPtr)
extractor(loggerPtr, is_bmp),
is_bmp_files(is_bmp)
{
am::configuration::ConfigurationReader reader;
auto conf = reader.getConfigurationFromFile(conf_path);
Expand Down
7 changes: 4 additions & 3 deletions AmApi.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,28 @@
#include "extraction/BmpExtractor.h"
#include "configuration/ConfigurationReader.hpp"
#include "common/Logger.hpp"
#include "extraction/MultipleBmpExtractor.h"
#include "extraction/MultipleExtractor.h"
#include "database/DataBaseCommunicator.h"

namespace am
{
class AmApi
{
public:
AmApi(const char *conf_path);
AmApi(const char *conf_path, bool is_bmp = false);
analyze::algorithm::DescObjects compare(const std::string &base_img, const std::string &cmp_img);
void compare_and_save_diff_img(const std::string &base_img, const std::string &cmp_img, std::string &&out_diff_img);
void enable_database_reports(const char *db_name);

private:
std::shared_ptr<am::common::Logger> loggerPtr;
extraction::MultipleBmpExtractor extractor;
extraction::MultipleExtractor extractor;
std::unique_ptr<analyze::algorithm::ObjectDetector> detector;

std::string base_img_path;
std::string cmp_img_path;
const char *conf_path;
std::unique_ptr<database::DataBaseCommunicator> dbcPtr;
bool is_bmp_files;
};
}
28 changes: 16 additions & 12 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
cmake_minimum_required (VERSION 2.6)
cmake_minimum_required (VERSION 3.0)

project (aquamarine)

if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
endif()
#if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
set(CMAKE_CXX_COMPILER /usr/bin/g++)
#endif()

set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall")
add_compile_options(-fno-rtti)
#set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall")
#add_compile_options(-fno-rtti)

find_package (Threads)
find_package (SQLite3)
find_package (JPEG REQUIRED)

include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${SQLite3_INCLUDE_DIRS})
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${SQLite3_INCLUDE_DIRS} ${JPEG_INCLUDE_DIR})

set(AM_SOURCE_FILES
analyze/AffinityComparer.cpp
Expand All @@ -26,14 +28,16 @@ set(AM_SOURCE_FILES
analyze/algorithm/ImagePair.cpp
analyze/algorithm/movement/MovementDetector.cpp
extraction/BmpExtractor.cpp
extraction/MultipleBmpExtractor.cpp
extraction/JpgExtractor.cpp
extraction/MultipleExtractor.cpp
common/Timers.hpp
database/DataBaseCommunicator.cpp
AmApi.cpp
)

add_library(aquamarine_lib STATIC ${AM_SOURCE_FILES} )
add_library(aquamarine_lib STATIC ${AM_SOURCE_FILES} ${JPEG_LIBRARIES})
#target_link_libraries(aquamarine_lib ${MY_JPEG})
add_executable(aquamarine main.cpp)

add_executable(aquamarine main.cpp database/DataBaseCommunicator.cpp)

target_link_libraries (aquamarine aquamarine_lib ${CMAKE_THREAD_LIBS_INIT} ${SQLite3_LIBRARIES})
target_link_libraries (aquamarine aquamarine_lib ${CMAKE_THREAD_LIBS_INIT} ${SQLite3_LIBRARIES} ${JPEG_LIBRARIES} )

Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ namespace am
{
namespace extraction
{
class IMultipleBmpExtractor
class IMultipleExtractor
{
public:
~IMultipleBmpExtractor() = default;
~IMultipleExtractor() = default;

virtual std::vector<common::types::Matrix<common::types::Color24b>> readFiles(std::vector<std::string> &&fileNames) = 0;
};
Expand Down
60 changes: 60 additions & 0 deletions extraction/JpgExtractor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@

#include "JpgExtractor.h"
#include "common/exceptions/FileAccessException.hpp"
#include "common/exceptions/AllocationException.hpp"
#include <future>
#include <vector>
#include <jpeglib.h>

namespace am
{
namespace extraction
{
using namespace common::types;


Matrix<Color24b> JpgExtractor::readFile(const std::string &fileName)
{
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;

FILE* infile = fopen(fileName.c_str(), "rb");
if (!infile) {
std::string errMsg = "File '" + fileName + "' could not be found!";
throw common::exceptions::FileAccessException(errMsg);
}

cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo, infile);
jpeg_read_header(&cinfo, TRUE);
jpeg_start_decompress(&cinfo);

JSAMPARRAY buffer;
buffer = (JSAMPARRAY)malloc(sizeof(JSAMPROW) * cinfo.output_height);
for (int i = 0; i < cinfo.output_height; i++)
{
buffer[i] = (JSAMPROW)malloc(sizeof(JSAMPLE) * cinfo.output_width * cinfo.output_components);
}
while (cinfo.output_scanline < cinfo.output_height)
{
jpeg_read_scanlines(&cinfo, buffer + cinfo.output_scanline, cinfo.output_height - cinfo.output_scanline);
}
Matrix<Color24b> data(cinfo.output_width, cinfo.output_height);
for (int i = 0; i < cinfo.output_height; i++)
{
for (int j = 0; j < cinfo.output_width; j++)
{
Color24b c24= reinterpret_cast<Color24b&>(buffer[i][j]);
//printf("%d %d %d\n", c24.r, c24.g, c24.b);
data(i, j) = c24;
}
}
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
fclose(infile);

return data;
}
}
}
21 changes: 21 additions & 0 deletions extraction/JpgExtractor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once

#include "common/types/Matrix.hpp"
#include "common/types/Color24b.hpp"

namespace am
{
namespace extraction
{
/// JpgExtractor class for RGB data extraction from JPG/JPEG file
class JpgExtractor
{
public:
JpgExtractor() = default;
~JpgExtractor() = default;

static common::types::Matrix<common::types::Color24b> readFile(const std::string &filePath);
};

}
}
37 changes: 0 additions & 37 deletions extraction/MultipleBmpExtractor.cpp

This file was deleted.

43 changes: 43 additions & 0 deletions extraction/MultipleExtractor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@

#include "MultipleExtractor.h"
#include <future>
#include "BmpExtractor.h"
#include "JpgExtractor.h"
#include "common/types/Color24b.hpp"

namespace am
{
namespace extraction
{
using namespace common::types;

MultipleExtractor::MultipleExtractor(std::shared_ptr<am::common::Logger> &logger, bool is_bmp)
: mLogger(logger),
mIsForBmp(is_bmp)
{
}

std::vector<Matrix<Color24b>> MultipleExtractor::readFiles(std::vector<std::string> &&fileNames)
{
std::vector<Matrix<Color24b>> result;
result.reserve(fileNames.size());
std::vector<std::future<Matrix<Color24b>>> futures;

for (size_t i = 0; i < fileNames.size(); ++i)
{
if(mIsForBmp)
futures.emplace_back(std::async(std::launch::deferred, BmpExtractor::readFile, fileNames[i]));
else
futures.emplace_back(std::async(std::launch::deferred, JpgExtractor::readFile, fileNames[i]));

mLogger->info("Reading of file:%s has been added in extraction queue.", fileNames[i].c_str());
}

for (auto &e : futures)
{
result.emplace_back(e.get());
}
return result;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include "common/types/Matrix.hpp"
#include "common/types/Color24b.hpp"
#include "common/Logger.hpp"
#include "IMultipleBmpExtractor.h"
#include "IMultipleExtractor.h"

namespace am
{
Expand All @@ -13,17 +13,18 @@ namespace am
// class for multiple reading files, given vector of fieNames will be
// fullfilled as return value with relative data from files
// Usage of async calls can reduce extraction time.
class MultipleBmpExtractor: public IMultipleBmpExtractor
class MultipleExtractor: public IMultipleExtractor
{
public:
MultipleBmpExtractor(std::shared_ptr<am::common::Logger> &logger);
~MultipleBmpExtractor() = default;
MultipleExtractor(std::shared_ptr<am::common::Logger> &logger, bool is_bmp=false);
~MultipleExtractor() = default;

// fill up the Matrices for each file provided in the input parameter
virtual std::vector<common::types::Matrix<common::types::Color24b>> readFiles(std::vector<std::string> &&fileNames) override;

private:
std::shared_ptr<am::common::Logger> mLogger;
bool mIsForBmp;
};
}
}
Binary file added inputs/_DSC4097.JPG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added inputs/_DSC4098.JPG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions inputs/configuration.csv
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Affinity_Threshold: 75
Minimum_Pixels_In_Object: 3
Pixel_Step: 2
Minimum_Pixels_In_Object: 100
Pixel_Step: 10
Calculation_Time_Limit: 50
Idle_Timeout: 5
Threads_Multiplier: 10.0
14 changes: 10 additions & 4 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ int main(int argc, char *argv[])
else
{
std::cout << "Use default parameters" << std::endl;
base_img_path = "inputs/rs_1.bmp";
cmp_img_path = "inputs/rs_2.bmp";
base_img_path = "inputs/_DSC4097.JPG";
cmp_img_path = "inputs/_DSC4098.JPG";
conf_path = "inputs/configuration.csv";
out_img_path = "compare_result.bmp";
}
Expand All @@ -39,7 +39,13 @@ int main(int argc, char *argv[])
rect.getRight(), rect.getPixelsCount());
}*/
amApi.enable_database_reports("results.db");
amApi.compare_and_save_diff_img(base_img_path, cmp_img_path, out_img_path);

const auto rects = amApi.compare(base_img_path, cmp_img_path);
for (auto &rect : rects)
{
printf("row:%zd col:%zd row:%zd col:%zd value:%zd\n",
rect.getMinHeight(), rect.getLeft(), rect.getMaxHeight(),
rect.getRight(), rect.getPixelsCount());
}
printf("rects %d\n", rects.size());
return 0;
}

0 comments on commit 661baa0

Please sign in to comment.